Skip to content

Commit

Permalink
improve sun rotation logic
Browse files Browse the repository at this point in the history
  • Loading branch information
amit9838 committed Apr 26, 2024
1 parent 58c8834 commit 8aca1ba
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 70 deletions.
61 changes: 32 additions & 29 deletions src/frontendCardDayNight.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
from datetime import datetime
import time
import gi
from gi.repository import Gtk
from .frontendUiDrawDayNight import *
from .utils import get_tz_offset_by_cord, get_cords, get_my_tz_offset_from_utc, is_dynamic_bg_enabled

gi.require_version("Gtk", "4.0")
gi.require_version("Adw", "1")
from gi.repository import Gtk

from .frontendUiDrawDayNight import *
from .utils import (
get_tz_offset_by_cord,
get_cords,
get_my_tz_offset_from_utc,
is_dynamic_bg_enabled,
get_time_difference,
)

my_tz_offset = get_my_tz_offset_from_utc()

class CardDayNight:
def __init__(self):
Expand All @@ -22,40 +26,40 @@ def __init__(self):

def get_sunset_sunrise_degree(self):
from .weatherData import daily_forecast_data as daily_data

t_data = get_time_difference(*get_cords())
time_diff = t_data.get("epoch_diff")
target_time = t_data.get("target_time")

my_tz_offset = get_my_tz_offset_from_utc()

tz_offset_from_curr_tz = get_tz_offset_by_cord(*get_cords())

sunrise_t, sunset_t = 0, 0
sunrise_ts, sunset_ts = 0, 0
for i, data in enumerate(daily_data.time.get("data")):
date_ = int(datetime.fromtimestamp(data + my_tz_offset + tz_offset_from_curr_tz).strftime(r"%d"))
date_ = int(
datetime.fromtimestamp(
data + my_tz_offset + tz_offset_from_curr_tz
).strftime(r"%d")
)
if date_ == datetime.today().date().day:
sunrise_t = daily_data.sunrise.get("data")[i]
sunset_t = daily_data.sunset.get("data")[i]
sunrise_ts = daily_data.sunrise.get("data")[i]
sunset_ts = daily_data.sunset.get("data")[i]
break


sunrise = datetime.fromtimestamp(sunrise_t + my_tz_offset + tz_offset_from_curr_tz).strftime("%I:%M %p")
sunset = datetime.fromtimestamp(sunset_t + my_tz_offset + tz_offset_from_curr_tz).strftime("%I:%M %p")
sunrise = datetime.fromtimestamp(sunrise_ts - time_diff).strftime("%I:%M %p")
sunset = datetime.fromtimestamp(sunset_ts - time_diff).strftime("%I:%M %p")

# Caclulate Sun rotation
current_time = datetime.fromtimestamp(time.time() + my_tz_offset + tz_offset_from_curr_tz)
current_time = current_time.hour + current_time.minute/60

sunrise_t = datetime.fromtimestamp(sunrise_t + my_tz_offset + tz_offset_from_curr_tz)
sunrise_t = sunrise_t.hour + sunrise_t.minute/60

sunset_t = datetime.fromtimestamp(sunset_t + my_tz_offset + tz_offset_from_curr_tz)
sunset_t = sunset_t.hour + sunset_t.minute/60

degree = 0
# For Day
if current_time < sunset_t:
degree = ((current_time - sunrise_t) / (sunset_t - sunrise_t)) * 180
degree = degree + 180
if target_time < (sunset_ts - time_diff):
degree = (target_time - (sunrise_ts - time_diff)) * 180 / (sunset_ts - sunrise_ts)
degree = degree + 180

# For Night
else:
degree = ((current_time - sunset_t) / (24-(sunset_t-sunrise_t))) * 180
degree = degree
degree = (target_time - (sunset_ts-time_diff))*180/(86400-(sunset_ts-sunrise_ts))

return sunrise, sunset, degree

Expand All @@ -65,7 +69,7 @@ def create_card(self):
card.halign = Gtk.Align.FILL
card.set_row_spacing(5)
card.set_css_classes(["view", "card", "custom_card"])

if is_dynamic_bg_enabled():
card.add_css_class("transparent_5")

Expand Down Expand Up @@ -112,4 +116,3 @@ def create_card(self):

obj = DrawDayNight(self.degree, 200, 100)
card_icon.attach(obj.img_box, 0, 1, 1, 1)

77 changes: 44 additions & 33 deletions src/frontendUiDrawDayNight.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,37 @@
import gi
import math
gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1')

gi.require_version("Gtk", "4.0")
gi.require_version("Adw", "1")
from gi.repository import Gtk
import cairo
from datetime import datetime
import time
from .utils import get_local_time
from .utils import get_cords, get_time_difference


class DrawDayNight:
def __init__(self,angle,width,height):
def __init__(self, angle, width, height):

self.angle_degrees = angle # Specify the rotation angle in degrees
self.width = width
self.height = height

self.drawing_area = Gtk.DrawingArea()
self.drawing_area.set_size_request(self.width+20,self.height+20)
self.drawing_area.set_css_classes(['drawing-padding'])
self.drawing_area.set_size_request(self.width + 20, self.height + 20)
self.drawing_area.set_css_classes(["drawing-padding"])
# self.drawing_area.connect("draw", self.on_draw)
self.drawing_area.set_draw_func(self.on_draw, None)

self.img_box = Gtk.Box()
self.img_box.append(self.drawing_area)

def on_draw(self, widget, cr, width, height, data):
# Create a Cairo surface
# Create a Cairo surface
context = cr
outer_radius = 43

num_rays = 8
sun_angle = self.angle_degrees #Degree
sun_angle = self.angle_degrees # Degree
sun_radius = 8
ray_length = 6

Expand All @@ -44,33 +45,41 @@ def on_draw(self, widget, cr, width, height, data):
center_x, center_y = width // 2, height // 2

# Define the center and radius of the disk (inner circle)
context.set_source_rgba(.8, .8, .8, .9) # Red
context.set_source_rgba(0.8, 0.8, 0.8, 0.9) # Red

# Create Upper half of circle (Day)
context.arc(center_x, center_y, outer_radius, 3.14, 2 * 3.14159) # Full circle (0 to 2π)
context.arc(
center_x, center_y, outer_radius, 3.14, 2 * 3.14159
) # Full circle (0 to 2π)
context.stroke()

# Create Lower half of circle (Night)
dash_length = 5
gap_length = 5
context.set_dash([dash_length, gap_length])
context.set_source_rgba(0.5, 0.5, 0.5, .7) # Red
context.arc(center_x, center_y, outer_radius, 0, 1 * 3.14159) # Full circle (0 to 2π)
context.set_source_rgba(0.5, 0.5, 0.5, 0.7) # Red
context.arc(
center_x, center_y, outer_radius, 0, 1 * 3.14159
) # Full circle (0 to 2π)
context.stroke()

# Midnight Mark
context.set_dash([1, 0])
context.set_source_rgba(0.5, 0.5, 0.5, .7)
context.move_to(center_x,center_y+outer_radius/1.2)
context.line_to(center_x,center_y+outer_radius)
context.set_source_rgba(0.5, 0.5, 0.5, 0.7)
context.move_to(center_x, center_y + outer_radius / 1.2)
context.line_to(center_x, center_y + outer_radius)
context.stroke()

# Clock
context.select_font_face("Sans", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
context.select_font_face(
"Sans", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL
)
context.set_font_size(13)
context.set_source_rgba(0.7, 0.7, 0.7, 1.0) # Black
t_data = get_time_difference(*get_cords())
target_time = t_data.get("target_time")

formatted_date_time = datetime.fromtimestamp(get_local_time()).strftime("%I:%M %p")
formatted_date_time = datetime.fromtimestamp(target_time).strftime("%I:%M %p")
text = formatted_date_time

# Calculate the position for text placement
Expand All @@ -88,8 +97,8 @@ def on_draw(self, widget, cr, width, height, data):
# Horizon text
text = _("Horizon")
# Calculate the position for text placement
text_x = center_x + outer_radius*1.3
text_y = center_y -10
text_x = center_x + outer_radius * 1.3
text_y = center_y - 10
# Move the text cursor to the calculated position
context.move_to(text_x, text_y)

Expand All @@ -99,38 +108,40 @@ def on_draw(self, widget, cr, width, height, data):
text2 = _("Midnight")
# Calculate the position for text placement
text_x = center_x - 30
text_y = center_y + outer_radius*1.3
text_y = center_y + outer_radius * 1.3
# Move the text cursor to the calculated position
context.move_to(text_x, text_y)

# Display the text along the circular path
context.show_text(text2)

# Choose sun color
if sun_angle>=180 and sun_angle<=360:
yellow = abs(1.2-(1-(sun_angle-170)/90))
if sun_angle >= 180 and sun_angle <= 360:
yellow = abs(1.2 - (1 - (sun_angle - 170) / 90))
if sun_angle > 270:
upper_limit = abs(1.2-(1-(360-170)/90))
lower_limit = abs(1.2-(1-(180-170)/90))
upper_limit = abs(1.2 - (1 - (360 - 170) / 90))
lower_limit = abs(1.2 - (1 - (180 - 170) / 90))
yellow = upper_limit - yellow + lower_limit
context.set_source_rgba(1, yellow, 0, 1.5) # Red
else:
context.set_source_rgba(.9, 0.9, 0.9, 1.0) # Red
context.set_source_rgba(0.9, 0.9, 0.9, 1.0) # Red

# Convert to radian
sun_angle_rad = math.radians(sun_angle) # Angle at which the disk is positioned (in radians)
sun_angle_rad = math.radians(
sun_angle
) # Angle at which the disk is positioned (in radians)

# # Calculate the position of the disk on the outer circle
disk_x = center_x + outer_radius * math.cos(sun_angle_rad)
disk_y = center_y + outer_radius * math.sin(sun_angle_rad)

# Sun
center_x,center_y = disk_x,disk_y
center_x, center_y = disk_x, disk_y
context.arc(center_x, center_y, sun_radius, 0, 2 * math.pi)
context.fill()

# Create sun rays
if sun_angle>=180 and sun_angle<=360:
if sun_angle >= 180 and sun_angle <= 360:
for i in range(num_rays):
angle = i * (2 * math.pi / num_rays)
x1 = center_x + (sun_radius + 2) * math.cos(angle)
Expand All @@ -143,10 +154,10 @@ def on_draw(self, widget, cr, width, height, data):

# Horizon Line
context.set_line_width(1)
context.set_source_rgba(.8, .8, 0.8, 1) # Red
context.set_source_rgba(0.8, 0.8, 0.8, 1) # Red
context.set_line_cap(cairo.LINE_CAP_ROUND)
context.move_to(width/6,height//2)
context.line_to(width,height//2)
context.move_to(width / 6, height // 2)
context.line_to(width, height // 2)
dash_length = 12
gap_length = 5
context.set_dash([dash_length, gap_length])
Expand Down
28 changes: 20 additions & 8 deletions src/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"baidu": "https://www.baidu.com/", # Specifically for china
}


# Check internet connection using socket connecton
def check_internet_socket():
try:
Expand All @@ -32,7 +33,7 @@ def check_internet_socket():
def check_internet_domain(url):
try:
request = requests.get(url, timeout=TIMEOUT)
print("Internet connection confirmed through: ",url)
print("Internet connection confirmed through: ", url)
return True
except (requests.ConnectionError, requests.Timeout) as exception:
return False
Expand All @@ -43,24 +44,26 @@ def check_internet_connection():
check_internet_socket()
or check_internet_domain(domains["google"])
or check_internet_domain(domains["wikipedia"])
or check_internet_domain(domains["baidu"])
or check_internet_domain(domains["baidu"])
):
return True

print("No internet!")
return False


def get_selected_city_coords():
settings = Gio.Settings.new("io.github.amit9838.mousam")

selected_city = int(str(settings.get_value("selected-city")))
added_cities = list(settings.get_value("added-cities"))
city_loc = added_cities[selected_city].split(",")
return city_loc[-2], city_loc[-1] # latitude,longitude


def is_dynamic_bg_enabled():
global global_settings
return global_settings.get_boolean('use-gradient-bg')
return global_settings.get_boolean("use-gradient-bg")


def create_toast(text, priority=0):
Expand All @@ -77,8 +80,8 @@ def convert_to_local_time(timestamp, timezone_stamp):


def get_cords():
settings = Gio.Settings(schema_id="io.github.amit9838.mousam")
selected_city_ = settings.get_string("selected-city")
global global_settings
selected_city_ = global_settings.get_string("selected-city")
return [float(x) for x in selected_city_.split(",")]


Expand Down Expand Up @@ -122,5 +125,14 @@ def get_tz_offset_by_cord(lat, lon):
return epoch_offset


def get_local_time():
return time.time() + get_my_tz_offset_from_utc() + get_tz_offset_by_cord(*get_cords())
def get_time_difference(target_latitude, target_longitude):
# Get current time in the target location using timeapi.io
url = f"https://timeapi.io/api/Time/current/coordinate?latitude={target_latitude}&longitude={target_longitude}"
target_time_response = requests.get(url)
target_time_data = target_time_response.json()
target_current_time = target_time_data["dateTime"]
target_time = datetime.strptime(target_current_time[:26], "%Y-%m-%dT%H:%M:%S.%f")

epoch_diff = time.time() - target_time.timestamp()
data = {"epoch_diff": epoch_diff, "target_time": target_time.timestamp()}
return data

0 comments on commit 8aca1ba

Please sign in to comment.