Skip to content

Commit

Permalink
Merge pull request #285 from ItachiSan/working-qt-position
Browse files Browse the repository at this point in the history
fix: QT Positioning
  • Loading branch information
l0drex committed Jun 19, 2024
2 parents 9188801 + 4fb491e commit 6249c3d
Showing 1 changed file with 52 additions and 26 deletions.
78 changes: 52 additions & 26 deletions yin_yang/position.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,48 @@
import logging
from time import sleep

import requests
from PySide6.QtCore import QObject
from PySide6.QtPositioning import QGeoPositionInfoSource, QGeoCoordinate, QGeoPositionInfo
from PySide6.QtCore import QObject, Slot
from PySide6.QtPositioning import (
QGeoPositionInfoSource,
QGeoCoordinate,
QGeoPositionInfo,
)

logger = logging.getLogger(__name__)


class QTPositionReceiver(QObject):
"""Small handler for QT positioning service."""

def __init__(self):
super().__init__()

# Create the position service and hook it to us
self._positionSource = QGeoPositionInfoSource.createSource(
"geoclue2", {"desktopId": "Yin-Yang"}, self
)
self._positionSource.positionUpdated.connect(self.handlePosition)

# Start the position service.
# This will only work after the app calls `exec()`.
self._positionSource.startUpdates()

# Get the initial last position.
self._lastPosition = self._positionSource.lastKnownPosition()

@Slot(QGeoPositionInfo)
def handlePosition(self, position: QGeoPositionInfo):
"""Track the position provided by the service."""
self._lastPosition = position

def lastKnownPosition(self):
"""Return the last known position, if valid."""
return self._lastPosition


position_handler = QTPositionReceiver()


def get_current_location() -> QGeoCoordinate:
try:
return get_qt_position()
Expand All @@ -19,53 +54,44 @@ def get_current_location() -> QGeoCoordinate:
except TypeError as e:
logger.warning(e)

raise TypeError('Unable to get current location')


parent = QObject()
location_source = QGeoPositionInfoSource.createDefaultSource(parent)
raise TypeError("Unable to get current location")


def get_qt_position() -> QGeoCoordinate:
if location_source is None:
raise TypeError('Location source is none')

pos: QGeoPositionInfo = location_source.lastKnownPosition()
if pos is None:
location_source.requestUpdate(10)
tries = 0
while pos is None and tries < 10:
pos = location_source.lastKnownPosition()
tries += 1
sleep(1)
"""Get the position via QT service"""
# Fetch the last known position
global position_handler
pos: QGeoPositionInfo = position_handler.lastKnownPosition()

coordinate = pos.coordinate()

if not coordinate.isValid():
raise TypeError('Coordinates are not valid')
raise TypeError("Coordinates are not valid")

return coordinate


# there is a freedesktop portal for getting the location,
# but it's not implemented by KDE, so I have no use for it


def get_ipinfo_position() -> QGeoCoordinate:
# use the old method as a fallback
try:
response = requests.get('https://www.ipinfo.io/loc')
response = requests.get("https://www.ipinfo.io/loc")
except Exception as e:
logger.error(e)
raise TypeError('Error while sending a request to get location')
raise TypeError("Error while sending a request to get location")

if not response.ok:
raise TypeError('Failed to get location from ipinfo.io')
raise TypeError("Failed to get location from ipinfo.io")

loc_response = response.text.removesuffix('\n').split(',')
loc_response = response.text.removesuffix("\n").split(",")
loc: [float] = [float(coordinate) for coordinate in loc_response]
assert len(loc) == 2, 'The returned location should have exactly 2 values.'
assert len(loc) == 2, "The returned location should have exactly 2 values."
coordinate = QGeoCoordinate(loc[0], loc[1])

if not coordinate.isValid():
raise TypeError('Coordinates are not valid')
raise TypeError("Coordinates are not valid")

return coordinate

0 comments on commit 6249c3d

Please sign in to comment.