Skip to content

Commit

Permalink
fix: Startup time + stuttering
Browse files Browse the repository at this point in the history
  • Loading branch information
matbme authored and mirkobrombin committed Apr 4, 2024
1 parent 51524e7 commit 09cc910
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 108 deletions.
42 changes: 31 additions & 11 deletions vanilla_installer/core/timezones.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import datetime
import logging

import requests
from gi.repository import GnomeDesktop
from gi.repository import GWeather
from gi.repository import GLib, GWeather
from zoneinfo import ZoneInfo

regions = {}
logger = logging.getLogger("VanillaInstaller::Timezones")

regions: dict[str, dict[str, dict[str, str]]] = {}
world = GWeather.Location.get_world()
parents = []
base = world
Expand All @@ -20,7 +22,9 @@
regions[current_region][child.get_name()] = {}
current_country = child.get_name()
elif child.get_level() == GWeather.LocationLevel.CITY:
regions[current_region][current_country][child.get_city_name()] = child.get_timezone_str()
regions[current_region][current_country][child.get_city_name()] = (
child.get_timezone_str()
)

if child.next_child(None) is not None:
parents.append(child)
Expand All @@ -34,21 +38,37 @@

all_timezones = dict(sorted(regions.items()))

def get_location():

def get_location(callback=None):
logger.info("Trying to retrieve timezone automatically")
try:
res = requests.get("http://ip-api.com/json?fields=49344", timeout=3).json()
if res["status"] != "success":
raise Exception(f"get_location: request failed with message '{res['message']}'")
nearest = world.find_nearest_city(res["lat"], res["lon"])
except Exception as e:
print(e)
logger.error(f"Failed to retrieve timezone: {e}")
nearest = None

return nearest
logger.info("Done retrieving timezone")

if callback:
logger.info("Running callback")
GLib.idle_add(callback, nearest)

def get_timezone_preview(tzname):
timezone = ZoneInfo(tzname)
now = datetime.datetime.now(timezone)

return now.strftime("%H:%M"), now.strftime("%A, %d %B %Y")
tz_preview_cache: dict[str, tuple[str, str]] = {}


def get_timezone_preview(tzname):
if tzname in tz_preview_cache:
return tz_preview_cache[tzname]
else:
timezone = ZoneInfo(tzname)
now = datetime.datetime.now(timezone)
now_str = (
"%02d:%02d" % (now.hour, now.minute),
now.strftime("%A, %d %B %Y"),
)
tz_preview_cache[tzname] = now_str
return now_str
2 changes: 1 addition & 1 deletion vanilla_installer/defaults/disk.py
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,7 @@ def __init__(self, window, partition_recipe, **kwargs):
)
)
self.group_partitions.add(entry)

if "auto" in partition_recipe:
for vg in partition_recipe["auto"]["vgs_to_remove"]:
entry = Adw.ActionRow()
Expand Down
20 changes: 10 additions & 10 deletions vanilla_installer/defaults/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from operator import attrgetter
from threading import Lock, Timer

from gi.repository import NM, NMA4, Adw, Gtk, GLib
from gi.repository import NM, NMA4, Adw, GLib, Gtk

from vanilla_installer.utils.run_async import RunAsync

Expand Down Expand Up @@ -115,9 +115,7 @@ def refresh_ui(self):
if not secure:
self.secure_icon.set_from_icon_name("warning-small-symbolic")
else:
self.secure_icon.set_from_icon_name(
"network-wireless-encrypted-symbolic"
)
self.secure_icon.set_from_icon_name("network-wireless-encrypted-symbolic")

self.secure_icon.set_visible(secure is not None)
if tooltip is not None:
Expand Down Expand Up @@ -254,6 +252,7 @@ def __init__(self, window, distro_info, key, step, **kwargs):
self.__key = key
self.__step = step
self.__nm_client = NM.Client.new()
self.__step_num = step["num"]

self.__devices = []
self.__wired_children = []
Expand All @@ -280,9 +279,12 @@ def __init__(self, window, distro_info, key, step, **kwargs):
self.__nm_client.connect("device-added", self.__add_new_device)
self.__nm_client.connect("device-added", self.__remove_device)
self.btn_next.connect("clicked", self.__window.next)
self.connect("realize", self.__try_skip_page)
self.__window.carousel.connect("page-changed", self.__try_skip_page)

def __try_skip_page(self, carousel=None, idx=None):
if idx is not None and idx != self.__step_num:
return

def __try_skip_page(self, data):
# Skip page if already connected to the internet
if self.has_eth_connection or self.has_wifi_connection:
self.__window.next()
Expand Down Expand Up @@ -316,9 +318,7 @@ def __get_network_devices(self):
eth_devices += 1
elif device_type == NM.DeviceType.WIFI:
device.connect("state-changed", self.__on_state_changed)
self.has_wifi_connection = (
device.get_active_connection() is not None
)
self.has_wifi_connection = device.get_active_connection() is not None
self.__refresh_wifi_list(device)
wifi_devices += 1
else:
Expand Down Expand Up @@ -419,7 +419,7 @@ def __poll_wifi_scan(self, conn: NM.DeviceWifi, last_known_scan: int):
GLib.idle_add(self.__refresh_wifi_list, conn)

def __refresh_wifi_list(self, conn: NM.DeviceWifi):
networks = {}
networks: dict[str, list[NM.AccessPoint]] = {}
for ap in conn.get_access_points():
ssid = ap.get_ssid()
if ssid is None:
Expand Down
140 changes: 65 additions & 75 deletions vanilla_installer/defaults/timezone.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,21 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

import logging
import re
import threading
import unicodedata

from gi.repository import Adw, Gtk, GLib
from gettext import gettext as _

from gi.repository import Adw, GLib, Gtk

from vanilla_installer.core.timezones import (
all_timezones,
get_location,
get_timezone_preview,
)
from vanilla_installer.utils.run_async import RunAsync

logger = logging.getLogger("VanillaInstaller::Timezone")


@Gtk.Template(resource_path="/org/vanillaos/Installer/gtk/widget-timezone.ui")
Expand All @@ -35,30 +38,22 @@ class TimezoneRow(Adw.ActionRow):
select_button = Gtk.Template.Child()
country_label = Gtk.Template.Child()

def __init__(self, title, subtitle, tz_name, parent, **kwargs):
def __init__(self, title, subtitle, tz_name, toggled_callback, parent_expander, **kwargs):
super().__init__(**kwargs)
self.title = title
self.subtitle = subtitle
self.parent = parent
self.tz_name = tz_name

tz_time, tz_date = get_timezone_preview(tz_name)
self.parent_expander = parent_expander

self.set_title(title)
self.set_subtitle(f"{tz_time}{tz_date}")
self.country_label.set_label(tz_name)

self.select_button.connect("toggled", self.__on_check_button_toggled)
self.select_button.connect("toggled", toggled_callback, self)
self.parent_expander.connect("notify::expanded", self.update_time_preview)

def __on_check_button_toggled(self, widget):
tz_split = self.tz_name.split("/", 1)
self.parent.selected_timezone["region"] = tz_split[0]
self.parent.selected_timezone["zone"] = tz_split[1]
self.parent.current_tz_label.set_label(self.tz_name)
self.parent.current_location_label.set_label(
_("(at %s, %s)") % (self.title, self.subtitle)
)
self.parent.timezone_verify()
def update_time_preview(self, *args):
tz_time, tz_date = get_timezone_preview(self.tz_name)
self.set_subtitle(f"{tz_time}{tz_date}")


@Gtk.Template(resource_path="/org/vanillaos/Installer/gtk/default-timezone.ui")
Expand All @@ -74,18 +69,23 @@ class VanillaDefaultTimezone(Adw.Bin):
search_controller = Gtk.EventControllerKey.new()
selected_timezone = {"region": "Europe", "zone": None}

expanders_list = {
country: region
for region, countries in all_timezones.items()
for country in countries.keys()
}
expanders_list = dict(
sorted(
{
country: region
for region, countries in all_timezones.items()
for country in countries.keys()
}.items()
)
)

def __init__(self, window, distro_info, key, step, **kwargs):
super().__init__(**kwargs)
self.__window = window
self.__distro_info = distro_info
self.__key = key
self.__step = step
self.__step_num = step["num"]

self.__expanders = []
self.__tz_entries = []
Expand All @@ -98,12 +98,24 @@ def __init__(self, window, distro_info, key, step, **kwargs):
self.search_controller.connect("key-released", self.__on_search_key_pressed)
self.entry_search_timezone.add_controller(self.search_controller)

def timezone_verify(self, *args):
valid = (
self.selected_timezone["region"]
and self.selected_timezone["zone"] is not None
)
self.btn_next.set_sensitive(valid)
def timezone_verify(self, carousel=None, idx=None):
if idx is not None and idx != self.__step_num:
return

def timezone_verify_callback(result, *args):
if result:
current_city = result.get_city_name()
current_country = result.get_country_name()
for entry in self.__tz_entries:
if current_city == entry.title and current_country == entry.subtitle:
self.selected_timezone["zone"] = current_city
self.selected_timezone["region"] = current_country
entry.select_button.set_active(True)
return
self.btn_next.set_sensitive(True)

thread = threading.Thread(target=get_location, args=(timezone_verify_callback,))
thread.start()

def get_finals(self):
try:
Expand All @@ -118,11 +130,7 @@ def get_finals(self):

def __on_search_key_pressed(self, *args):
def remove_accents(msg: str):
out = (
unicodedata.normalize("NFD", msg)
.encode("ascii", "ignore")
.decode("utf-8")
)
out = unicodedata.normalize("NFD", msg).encode("ascii", "ignore").decode("utf-8")
return str(out)

search_entry = self.entry_search_timezone.get_text().lower()
Expand All @@ -147,48 +155,30 @@ def remove_accents(msg: str):
visible_entries = 0
current_country = entry.subtitle
current_expander += 1
visible_entries += 1 if match else 0
visible_entries += match

def __on_row_toggle(self, __check_button, widget):
tz_split = widget.tz_name.split("/", 1)
self.selected_timezone["region"] = tz_split[0]
self.selected_timezone["zone"] = tz_split[1]
self.current_tz_label.set_label(widget.tz_name)
self.current_location_label.set_label(_("(at %s, %s)") % (widget.title, widget.subtitle))
self.btn_next.set_sensitive(True)

def __generate_timezone_list_widgets(self):
def __populate_expanders():
widgets = {}
first_elem = None
for country, region in dict(sorted(self.expanders_list.items())).items():
if len(all_timezones[region][country]) > 0:
country_tz_expander_row = Adw.ExpanderRow.new()
country_tz_expander_row.set_title(country)
country_tz_expander_row.set_subtitle(region)
widgets[country_tz_expander_row] = []
for city, tzname in sorted(all_timezones[region][country].items()):
timezone_row = TimezoneRow(city, country, tzname, self)
if first_elem is None:
first_elem = timezone_row
else:
timezone_row.select_button.set_group(
first_elem.select_button
)
widgets[country_tz_expander_row].append(timezone_row)
return widgets

def __set_located_timezone(result, *args):
if not result:
return
current_city = result.get_city_name()
current_country = result.get_country_name()
for entry in self.__tz_entries:
if current_city == entry.title and current_country == entry.subtitle:
self.selected_timezone["zone"] = current_city
self.selected_timezone["region"] = current_country
entry.select_button.set_active(True)
return

def __callback(widgets, *args):
for expander, timezone_rows in widgets.items():
def __populate_expander(expander, region, country, *args):
for city, tzname in all_timezones[region][country].items():
timezone_row = TimezoneRow(city, country, tzname, self.__on_row_toggle, expander)
self.__tz_entries.append(timezone_row)
if len(self.__tz_entries) > 0:
timezone_row.select_button.set_group(self.__tz_entries[0].select_button)
expander.add_row(timezone_row)

for country, region in self.expanders_list.items():
if len(all_timezones[region][country]) > 0:
expander = Adw.ExpanderRow.new()
expander.set_title(country)
expander.set_subtitle(region)
self.all_timezones_group.add(expander)
self.__expanders.append(expander)
for timezone_row in timezone_rows:
expander.add_row(timezone_row)
self.__tz_entries.append(timezone_row)
RunAsync(get_location, __set_located_timezone)

RunAsync(__populate_expanders, __callback)
GLib.idle_add(__populate_expander, expander, region, country)
3 changes: 2 additions & 1 deletion vanilla_installer/defaults/welcome.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from vanilla_installer.windows.dialog_recovery import VanillaRecoveryDialog
from vanilla_installer.windows.dialog_poweroff import VanillaPoweroffDialog


@Gtk.Template(resource_path="/org/vanillaos/Installer/gtk/default-welcome.ui")
class VanillaDefaultWelcome(Adw.Bin):
__gtype_name__ = "VanillaDefaultWelcome"
Expand All @@ -37,7 +38,7 @@ def __init__(self, window, distro_info, key, step, **kwargs):

distro_name = self.__distro_info.get("name", "Vanilla OS")
distro_logo = self.__distro_info.get("logo", "org.vanillaos.Installer-flower")

self.status_page.set_icon_name(distro_logo)
self.status_page.set_title(f"Welcome to {distro_name}!")

Expand Down
Loading

0 comments on commit 09cc910

Please sign in to comment.