[-]
[+]
|
Changed |
modrana_0.43.4.spec
|
|
[-]
[+]
|
Deleted |
modrana_0.43.3.tar.gz/modrana/opt/modrana/modules/device_modules/n900_maemo5_autoconnect_dbus.sh
^
|
@@ -1,3 +0,0 @@
-#/bin/sh
-
-dbus-send --system --type=method_call --dest=com.nokia.icd /com/nokia/icd com.nokia.icd.connect string:"[ANY]" uint32:0
\ No newline at end of file
|
[-]
[+]
|
Changed |
modrana_0.43.4.tar.gz/modrana/opt/modrana/core/constants.py
^
|
@@ -23,6 +23,18 @@
DEFAULT_THEME_ID = "default"
+LOCATION_TIMEOUT = 30 # in seconds
+INTERNET_CONNECTIVITY_TIMEOUT = 30 # in seconds
+
+ONLINE = True
+OFFLINE = False
+CONNECTIVITY_UNKNOWN = None
+
+# tile storage
+DEFAULT_TILE_STORAGE_TYPE = "files"
+TILE_STORAGE_FILES = "files"
+TILE_STORAGE_SQLITE = "sqlite"
+
# GTK GUI
PANGO_ON = '<span color="green">ON</span>'
PANGO_OFF = '<span color="red">OFF</span>'
@@ -30,11 +42,17 @@
# threads
THREAD_POI_SEARCH = "modRanaPOISearch"
THREAD_ADDRESS_SEARCH = "modRanaAddressSearch"
+THREAD_WIKIPEDIA_SEARCH_NOMINATIM = "modRanaWikipediaSearchNominatim"
THREAD_REVERSE_GEOCODING = "modRanaReverseGeocoding"
-THREAD_TESTING_PROVIDER = "modRanaTestingProvider"
+THREAD_LOCAL_SEARCH_GOOGLE = "modRanaLocalSearchGoogle"
THREAD_ROUTING_ONLINE_GOOGLE = "modRanaRoutingOnlineGoogle"
THREAD_ROUTING_OFFLINE_MONAV = "modRanaRoutingOfflineMonav"
+THREAD_CONNECTIVITY_CHECK = "modRanaConnectivityCheck"
+THREAD_LOCATION_CHECK = "modRanaCurrentPositionCheck"
+
+THREAD_TESTING_PROVIDER = "modRanaTestingProvider"
+
# device types
DEVICE_TYPE_DESKTOP = 1
DEVICE_TYPE_SMARTPHONE = 2
|
[-]
[+]
|
Changed |
modrana_0.43.4.tar.gz/modrana/opt/modrana/core/providers.py
^
|
@@ -3,7 +3,6 @@
from core import threads, constants
-
class DummyController(object):
"""A default dummy object that implements the
task controller interface that modRanaThreads have"""
@@ -11,13 +10,14 @@
def __init__(self):
self.status = None
self.progress = None
+ self.callback = None
class POIProvider(object):
def __init__(self, threadName=constants.THREAD_POI_SEARCH):
self._threadName = threadName
- def search(self, term=None, around=None, controller=DummyController()):
+ def search(self, term=None, around=None, controller=DummyController(), **kwargs):
"""Search for POI using a textual search query
:param term: search term
:type term: str
@@ -29,7 +29,7 @@
"""
pass
- def searchAsync(self, callback, term=None, around=None):
+ def searchAsync(self, callback, term=None, around=None, **kwargs):
"""Perform asynchronous search
:param callback: result handler
:type term: a callable
@@ -45,7 +45,8 @@
thread.target = lambda: self.search(
term=term,
around=around,
- controller=thread
+ controller=thread,
+ **kwargs
)
thread.callback = callback
@@ -95,7 +96,6 @@
:returns: a list of routes (Way objects), None if search failed
:rtype: list
"""
- pass
# lambda is used to pass all needed arguments to the search function
# and passing the result to the callback,
# but not actually executing it until the thread is started
@@ -123,9 +123,9 @@
class RouteParameters(object):
def __init__(self,
+ routeMode=constants.ROUTE_CAR,
avoidTollRoads=False,
avoidHighways=False,
- routeMode=constants.ROUTE_CAR,
language=constants.ROUTE_DEFAULT_LANGUAGE,
addressRoute=False):
self._avoidTollRoads = avoidTollRoads
@@ -164,6 +164,10 @@
"""
return self._addressRoute
+ @addressRoute.setter
+ def addressRoute(self, value):
+ self._addressRoute = value
+
class RoutingResult(object):
"""This class acts as a wrapper for the results of a routing lookup,
the main "payload" is the route object, but it also wraps other
@@ -208,3 +212,4 @@
def lookupDuration(self):
return self._lookupDuration
+
|
[-]
[+]
|
Added |
modrana_0.43.4.tar.gz/modrana/opt/modrana/core/requirements.py
^
|
@@ -0,0 +1,224 @@
+# -*- coding: utf-8 -*-
+#----------------------------------------------------------------------------
+# ModRana check and acquire various requirements
+#----------------------------------------------------------------------------
+# Copyright 2013, Martin Kolman
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# 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 time
+import functools
+from core import constants
+from core.point import Point
+from core.singleton import modrana
+
+def locateCurrentPosition(controller=None):
+ """Try to locate current position and return it when done or time out"""
+ result = None
+ sleepTime = 0.5 # in seconds
+ pos = modrana.get('pos', None)
+ fix = modrana.get('fix', 1)
+ # check if GPS usage is explicitly disabled in modRana
+ gpsEnabled = modrana.get('GPSEnabled')
+ if gpsEnabled == False:
+ if pos:
+ modrana.notify("GPS OFF, using last known position", 5000)
+ return Point(*pos)
+ else:
+ modrana.notify("GPS OFF, no last known position", 5000)
+ return None
+
+ if fix > 1 and pos:
+ return Point(*pos) # fix found, return it at once
+
+ # check if GPS hardware has been enabled
+ location = modrana.m.get("location")
+ if not location.enabled:
+ # location usage has not be disabled but location
+ # has not been started, so start location
+ location.startLocation()
+
+ # wait for the fix
+ startTimestamp = time.time()
+ elapsed = 0
+ if controller:
+ controller.status = "GPS fix in progress"
+ while elapsed < constants.LOCATION_TIMEOUT:
+ pos = modrana.get('pos', None)
+ fix = modrana.get('fix', 1)
+ if fix > 1 and pos:
+ break
+ time.sleep(sleepTime)
+ elapsed = time.time() - startTimestamp
+ if fix > 1 and pos: # got GPS fix ?
+ return Point(*pos)
+ else: # no GPS lock
+ pos = modrana.get("pos")
+ if pos:
+ modrana.notify("no fix, using last known position", 5000)
+ return Point(*pos)
+ else:
+ modrana.notify("failed to get GPS fix", 5000)
+ return None
+
+def checkConnectivity(controller=None):
+ """Check for Internet connectivity - if no Internet connectivity is available,
+ wait for up to 30 seconds and then fail (this is used to handle cases where
+ the device was offline and the Internet connection is just being established)"""
+ status = modrana.dmod.connectivityStatus
+ if status is constants.CONNECTIVITY_UNKNOWN: # Connectivity status monitoring not supported
+ return status # skip
+ elif status is constants.ONLINE:
+ return status # Internet connectivity is most probably available
+ elif status is constants.OFFLINE:
+ startTimestamp = time.time()
+ elapsed = 0
+ if controller:
+ controller.status = "waiting for Internet connectivity"
+ while elapsed < constants.INTERNET_CONNECTIVITY_TIMEOUT:
+ status = modrana.dmod.connectivityStatus
+ print('requirements: waiting for internet connectivity')
+ print(status)
+ if status == True or status is None:
+ break
+ # check if the thread was cancelled
+ if controller and controller.callback is None:
+ # the thread was cancelled
+ print("requirements: connectivity status check cancelled")
+ status = constants.CONNECTIVITY_UNKNOWN
+ break
+ time.sleep(1)
+ elapsed = time.time() - startTimestamp
+ if status is constants.OFFLINE:
+ modrana.notify("requirements: failed to connect to the Internet")
+ return status
+ else:
+ print('requirements: warning, unknown connection status:')
+ print(status)
+ return status
+
+def gps(conditional=False):
+ """The given function requires GPS,
+ start it and wait for a fix or timeout
+
+ :param kwargTrigger: if the key specified is in kwargs of the
+ wrapped function and it's value evaluates to true, then start GPS
+ :type kwargTrigger: hashable type other than None
+ """
+ def decorator(function):
+ @functools.wraps(function)
+ def wrapper(*args, **kwargs):
+ # check if GPS is needed
+ controller=kwargs.get("controller")
+ needsGPS = True
+ if conditional:
+ needsGPS = kwargs.get("gps")
+ if needsGPS:
+ del kwargs["gps"] # not needed by the wrapped function
+ pos = locateCurrentPosition(controller=controller)
+ if pos:
+ kwargs["around"] = pos # feed the position as the around argument
+ else:
+ # requirements not fulfilled,
+ # disable the callback and return an empty list
+ if controller:
+ controller.callback = None
+ return []
+ # requirement fulfilled,
+ # call the wrapped function
+ return function(*args, **kwargs)
+ return wrapper
+ return decorator
+
+def internet(function):
+ """The given function requires Internet, start it
+ and wait for it to connect or timeout
+ """
+ @functools.wraps(function)
+ def wrapper(*args, **kwargs):
+ controller=kwargs.get("controller")
+ # tell the device module we need Internet connectivity
+ modrana.dmod.enableInternetConnectivity()
+ # check if it is available
+ status = checkConnectivity(controller=controller)
+ if status is constants.OFFLINE:
+ # requirement not fulfilled (we are offline),
+ # disable the callback and return an empty list
+ if controller:
+ controller.callback = None
+ return []
+ # requirement fulfilled,
+ # call the wrapped function
+ return function(*args, **kwargs)
+ return wrapper
+
+
+def startGPS(conditional=False):
+ """Start GPS
+
+ :param conditional: if true, check for the "gps"
+ key in the kwargs of the wrapped function,
+ if the value evaluates as True, start GPS
+ :type conditional: bool
+ """
+ def decorate(function):
+ @functools.wraps(function)
+ def wrapper(*args, **kwargs):
+ start = True
+ # check if the kwargs trigger is enabled
+ if conditional:
+ start = kwargs.get("gps")
+ # check if GPS usage is enabled in modRana
+ gpsEnabled = modrana.get('GPSEnabled')
+ if start and gpsEnabled:
+ location = modrana.m.get('location')
+ if location:
+ location.startLocation()
+
+ return function(*args, **kwargs)
+ return wrapper
+ return decorate
+
+def startInternet(function):
+ """Start Internet"""
+
+ @functools.wraps(function)
+ def wrapper(*args, **kwargs):
+ # tell the device module we need Internet connectivity
|
[-]
[+]
|
Added |
modrana_0.43.4.tar.gz/modrana/opt/modrana/core/singleton.py
^
|
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+#----------------------------------------------------------------------------
+# ModRana singleton access
+#----------------------------------------------------------------------------
+# Copyright 2013, Martin Kolman
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#---------------------------------------------------------------------------
+modrana = None
\ No newline at end of file
|
[-]
[+]
|
Changed |
modrana_0.43.4.tar.gz/modrana/opt/modrana/core/startup.py
^
|
@@ -142,6 +142,13 @@
default=None,
action="store"
)
+ # startup debugging - don't disable stdout
+ parser.add_argument(
+ '--debug-startup',
+ help="startup debugging - don't disable stdout",
+ default=None,
+ action="store_true"
+ )
self.args = parser.parse_args()
@@ -151,8 +158,25 @@
return self.args
def handleEarlyTasks(self):
+ """Handle CLI arguments that can be handled before the general modRana startup
+ -> this usually means some "simple" tasks that return some results to
+ standard output and then shut-down modRana
+ EX.: do an address search, return static map URL and quit
"""
- handle CLI arguments that can be handled before the general modRana startup
+ # if any of those argument combinations are specified,
+ # we need to disable stdout, or else regular modRana
+ # startup will spam the CLI output
+ if self.args.return_static_map_url:
+ if self.args.local_search or \
+ self.args.address_search is not None or \
+ self.args.wikipedia_search is not None:
+ self._disableStdout()
+ elif self.args.return_current_coordinates:
+ self._disableStdout()
+
+ def handleNonGUITasks(self):
+ """Handle CLI arguments that can be handled before the general modRana startup,
+ but require a loaded device module
-> this usually means some "simple" tasks that return some results to
standard output and then shut-down modRana
EX.: do an address search, return static map URL and quit
@@ -169,6 +193,7 @@
self._earlyReturnCoordinates()
+
def handlePostFirstTimeTasks(self):
"""
handle CLI arguments that should take effect once modrana is fully stared
@@ -250,6 +275,11 @@
self._disableStdout()
+ # local search need Internet connectivity, trigger
+ # Internet initialization now, the search function decorator
+ # will wait for it to finish
+ self.modrana.dmod.enableInternetConnectivity()
+
# load the online services module
online = self.modrana._loadModule("mod_onlineServices", "onlineServices")
@@ -259,10 +289,13 @@
# now check if a location for the local search was provided from CLI or if we need to find our location
# using GPS or equivalent
+ from core.point import Point
+
location = self._getLocalSearchLocation()
if location is not None:
# we use the location provided from CLI, no need to load & start location
if self._useLastKnownPos(location):
+ # get last known position (if any)
pos = self._getCurrentPosition(loadLocationModule=True, useLastKnown=True)
if pos is None:
self._enableStdout()
@@ -271,20 +304,21 @@
self._exit(LOCAL_SEARCH_CURRENT_POSITION_UNKNOWN_ERROR)
else:
lat, lon = pos
- points = online.localSearchLL(query, lat, lon)
- else:
- points = online.localSearch(query, location)
-
+ # replace the use-last-known flag with the actual location
+ location = Point(lat, lon)
else:
# we need to determine our current location - the location module needs to be loaded & used
pos = self._getCurrentPosition(loadLocationModule=True)
if pos is not None:
lat, lon = pos
- points = online.localSearchLL(query, lat, lon)
+ location = Point(lat, lon)
else:
# done - no position found
self._exit(LOCAL_SEARCH_CURRENT_POSITION_UNKNOWN_ERROR)
+ # do the search
+ points = online.localSearch(query, location)
+
# local search results processing
self._returnStaticMapUrl(points, online)
@@ -379,7 +413,6 @@
# -> Internet is needed for a quick fix & the search itself
# -> if the device is offline, it might need this "nudge"
# to reconnect
- self.modrana.dmod.enableInternetConnectivity()
print("startup: searching where is the CLI-provided address")
query = self.args.address_search
@@ -392,7 +425,6 @@
# -> Internet is needed for a quick fix & the search itself
# -> if the device is offline, it might need this "nudge"
# to reconnect
- self.modrana.dmod.enableInternetConnectivity()
print("startup: searching Wikipedia for CLI-provided query")
query = self.args.wikipedia_search
@@ -427,8 +459,6 @@
# do we need to load the location module ?
# we usually need to load it if we handle an early task that happens before regular startup
if loadLocationModule:
- # the location module might need the device module to handle location on some devices
- self.modrana._loadDeviceModule()
# load the location module
l = self.modrana._loadModule("mod_location", "location")
# register fix CB
@@ -440,6 +470,10 @@
else:
l = self.modrana.m.get("location", None)
+ # calling l.startLocation(startMainLoop=True) will start the
+ # main loop and block the execution of this function until the
+ # main loop is killed by the fix watch
+ #
# the fix watch will kill the main loop once a 3D fix is
# established or once it times out,
# then the rest of the code in this function will be executed
@@ -497,16 +531,22 @@
def _enableStdout(self):
"""enable stdout output"""
- sys.stdout = self.originalStdout
- self.originalStdout = None
+ if self.originalStdout:
+ sys.stdout = self.originalStdout
+ self.originalStdout = None
def _disableStdout(self):
"""disable stdout output
-> this is mainly used for CLI processing so that modRanas status messages don't get into the output
that will be parsed by outside programs or scripts
"""
- self.originalStdout = sys.stdout
- sys.stdout = self
+ # if startup debugging is enabled, don't disable stdout
+ if self.args.debug_startup:
+ return
+
+ if self.originalStdout is None:
+ self.originalStdout = sys.stdout
+ sys.stdout = self
def write(self, s):
"""a write function that does nothing for stdout redirection"""
|
[-]
[+]
|
Changed |
modrana_0.43.4.tar.gz/modrana/opt/modrana/core/utils.py
^
|
@@ -188,12 +188,19 @@
return False
else:
print("creating path: %s" % newPath)
- head, tail = os.path.split(newPath)
- if head and not os.path.isdir(head):
- os.makedirs(head)
- if tail:
- os.mkdir(newPath)
- return True
+ try:
+ head, tail = os.path.split(newPath)
+ if head and not os.path.isdir(head):
+ os.makedirs(head)
+ if tail:
+ os.mkdir(newPath)
+ return True
+ except Exception:
+ print("path creation failed")
+ import sys
+ e = sys.exc_info()[1]
+ print(e)
+ return False
#from
# http://stackoverflow.com/questions/3167154/
|
[-]
[+]
|
Changed |
modrana_0.43.4.tar.gz/modrana/opt/modrana/data/directions_filter.csv
^
|
@@ -75,7 +75,7 @@
Plz ;Plaza
Rd ;Road
Sq ;Square
-St.;Street
+St\.;Street
St ;Street
Tce ;Terrace
Trk ;Track
|
[-]
[+]
|
Changed |
modrana_0.43.4.tar.gz/modrana/opt/modrana/modrana.py
^
|
@@ -30,6 +30,7 @@
import marshal
import traceback
import imp
+import platform
# import core modules/classes
from core import startup
from core import utils
@@ -37,6 +38,7 @@
from core import configs
from core import threads
from core import gs
+from core import singleton
from core.backports import six
# record that imports-done timestamp
importsDoneTimestamp = time.time()
@@ -57,6 +59,8 @@
"""
def __init__(self):
+ singleton.modrana = self
+
self.timing = []
self.addCustomTime("modRana start", startTimestamp)
self.addCustomTime("imports done", importsDoneTimestamp)
@@ -111,6 +115,7 @@
if version is None:
version = "unknown version"
print(" %s" % version)
+ print(" Python %s" % platform.python_version())
# add the configs handling core module
self.configs = configs.Configs(self)
@@ -138,6 +143,10 @@
# device module first
self._loadDeviceModule()
+ # handle tasks that require the device
+ # module but not GUI
+ self.startup.handleNonGUITasks()
+
# then the GUI module
self._loadGUIModule()
@@ -157,6 +166,8 @@
def _loadDeviceModule(self):
"""Load the device module"""
+ if self.dmod: # don't reload the module
+ return
# get the device module string
# (a unique device module string identificator)
@@ -629,6 +640,13 @@
else:
return False
+ def notify(self, message, msTimeout=0, icon=""):
+ notify = self.m.get('notification')
+ if notify:
+ # the notification module counts timeout in seconds
+ sTimeout = msTimeout / 1000.0
+ notify.handleNotification(message, sTimeout, icon)
+
def getModes(self):
"""return supported modes"""
modes = {
|
[-]
[+]
|
Changed |
modrana_0.43.4.tar.gz/modrana/opt/modrana/modules/device_modules/base_device_module.py
^
|
@@ -1,3 +1,4 @@
+from __future__ import with_statement # for Python 2.5
# -*- coding: utf-8 -*-
#----------------------------------------------------------------------------
# Base class for Rana device-specific modules
@@ -20,14 +21,16 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#---------------------------------------------------------------------------
+from core import constants
from modules.base_module import RanaModule
-from core import signal
+from core.signal import Signal
+
class DeviceModule(RanaModule):
"""A modRana device module"""
def __init__(self, m, d, i):
RanaModule.__init__(self, m, d, i)
- self.connectivityChanged = signal.Signal()
+ self.internetConnectivityChanged = Signal()
def getDeviceIDString(self):
"""
@@ -223,12 +226,29 @@
"""
pass
- def getInternetConnectivityStatus(self):
+ @property
+ def connectivityStatus(self):
"""report the current status of internet connectivity on the device
None - status reporting not supported or status unknown
True - connected to the Internet
False - disconnected from the Internet
"""
+ connected = constants.OFFLINE
+ # open the /proc/net/route file
+ with open('/proc/net/route', 'rc') as f:
+ for line in f:
+ # the line is delimited by tabulators
+ lineSplit = line.split('\t')
+ # check if the length is valid
+ if len(lineSplit) >= 11:
+ if lineSplit[1] == '00000000' and lineSplit[7] == '00000000':
+ # if destination and mask are 00000000,
+ # it is probably an Internet connection
+ connected = constants.ONLINE
+ break
+ return connected
+
+
def enableInternetConnectivity(self):
"""try to make sure that the device connects to the internet"""
|
[-]
[+]
|
Changed |
modrana_0.43.4.tar.gz/modrana/opt/modrana/modules/device_modules/device_n900.py
^
|
@@ -26,7 +26,7 @@
#N900 specific:
import dbus.glib
-from core import gs
+from core import gs, constants
# only import GTK, Hildon & Liblocation when using GTK GUI
if gs.GUIString == "GTK":
import hildon
@@ -73,7 +73,9 @@
print("N900: DBUS initialized")
# Internet connectivity related
- self.connectivityStatus = False
+
+ # status from the Internet Connectivity Daemon
+ self._connectivityStatusICD = constants.OFFLINE
self.conicConnection = None
# Mainloop for headless location support
@@ -339,7 +341,7 @@
optionsButton = gtk.Button("Options")
optionsButton.connect('clicked', self._switchToMenu, 'options')
searchButton = gtk.Button("Search")
- searchButton.connect('clicked', self._switchToMenu, 'search')
+ searchButton.connect('clicked', self._switchToMenu, 'searchWhat')
routeButton = gtk.Button("Route")
routeButton.connect('clicked', self._switchToMenu, 'route')
@@ -604,28 +606,42 @@
# ** Internet connectivity **
- def getInternetConnectivityStatus(self):
- """report Internet connectivity status based on data from libconic"""
- return self.connectivityStatus
-
def _connectionStateCB(self, connection, event):
"""handle Internet connectivity state changes"""
- # print("connection_cb(%s, %s)" % (connection, event))
- status = event.get_status()
- error = event.get_error()
- iap_id = event.get_iap_id()
- bearer = event.get_bearer_type()
-
- if status == conic.STATUS_CONNECTED:
- self.connectivityStatus = True
- elif status == conic.STATUS_DISCONNECTED:
- self.connectivityStatus = False
- elif status == conic.STATUS_DISCONNECTING:
- self.connectivityStatus = False
+ #print("connection_cb(%s, %s)" % (connection, event))
+ conic_status = event.get_status()
+ #print(conic_status)
+ #error = event.get_error()
+ #iap_id = event.get_iap_id()
+ #bearer = event.get_bearer_type()
+ status = constants.CONNECTIVITY_UNKNOWN
+ if conic_status == conic.STATUS_CONNECTED:
+ status = constants.ONLINE
+ #print("CONIC CONNECTED")
+ elif conic_status == conic.STATUS_DISCONNECTED:
+ status = constants.OFFLINE
+ #print("CONIC DISCONNECTED")
+ elif conic_status == conic.STATUS_DISCONNECTING:
+ status = constants.OFFLINE
+ #print("CONIC DISCONNECTING")
+ self._connectivityStatusICD = status
+ # trigger the connectivity status changed signal
+ self.internetConnectivityChanged(status)
def enableInternetConnectivity(self):
- """autoconnect to the Internet using DBUS"""
- subprocess.call(["sh", "modules/device_modules/n900_maemo5_autoconnect_dbus.sh"])
+ """Autoconnect to the Internet using DBUS"""
+ # if connectivity is requested like this,
+ # the callback will be called at once if we are online,
+ # so current connectivity state can be determined
+ self.conicConnection.request_connection(conic.CONNECT_FLAG_AUTOMATICALLY_TRIGGERED)
+
+ @property
+ def connectivityStatus(self):
+ # The conic/ICD callback is called both once registered
+ # and also when trying to enable connectivity, so we can use data
+ # from the callback to represent the connectivity state,
+ # overriding the portable connectivityStatus implementation in base_device_module
+ return self._connectivityStatusICD
def getDeviceType(self):
return DEVICE_TYPE_SMARTPHONE
|
[-]
[+]
|
Changed |
modrana_0.43.4.tar.gz/modrana/opt/modrana/modules/gui_modules/gui_qml/gui_qml.py
^
|
@@ -643,6 +643,8 @@
img = QImage()
# lod the image from in memory buffer
# img.loadFromData(f.read())
+ #tileData = QByteArray(tileData)
+ tileData = str(tileData)
img.loadFromData(tileData)
# cleanup
# f.close()
@@ -650,7 +652,6 @@
return img
except Exception:
import sys
-
e = sys.exc_info()[1]
print("QML GUI: icon image provider: loading tile failed")
print(e)
@@ -659,9 +660,23 @@
class MapTiles(QtCore.QObject):
+ storageTypeChanged = QtCore.Signal()
+
def __init__(self, gui):
QtCore.QObject.__init__(self)
self.gui = gui
+ # assign watch to the "tileStorageType" key
+ # so that the property would correctly reflect the
+ # changed value
+ #self.gui.modrana.watch("tileStorageType",
+ # lambda x: x.storageTypeChanged.emit())
+ self.gui.modrana.watch("tileStorageType",
+ self._storageTypeCB)
+ # we use a lambda for the callback, so we don't have a define
+ # a separate callback handler
+
+ def _storageTypeCB(self, *args, **kwargs):
+ self.storageTypeChanged.emit()
@QtCore.Slot(result=int)
def tileserverPort(self):
@@ -691,6 +706,18 @@
# print("downloading, try later")
return False
+ def _getStorageType(self):
+ self.gui.modrana.get("tileStorageType", "files")
+
+ def _setStorageType(self, value):
+ self.gui.modrana.set("tileStorageType", value)
+
+ storageType = QtCore.Property(six.text_type,
+ _getStorageType,
+ _setStorageType,
+ notify=storageTypeChanged
+ )
+
class MapLayers(QtCore.QObject):
def __init__(self, gui):
|
[-]
[+]
|
Changed |
modrana_0.43.4.tar.gz/modrana/opt/modrana/modules/gui_modules/gui_qml/ic/OptionsMapPage.qml
^
|
@@ -3,15 +3,43 @@
import QtQuick 1.1
import "qtc/PageStatus.js" as PageStatus
import "./qtc"
+import com.nokia.meego 1.0
BasePage {
id: compassPage
headerText : "Map"
bottomPadding : 0
-/*
content {
+ Column {
+ anchors.top : parent.top
+ anchors.left : parent.left
+ anchors.right : parent.right
+ anchors.topMargin : C.style.main.spacing
+ anchors.leftMargin : C.style.main.spacing
+ anchors.rightMargin : C.style.main.spacing
+ spacing : C.style.main.spacingBig * 2
+ width : parent.width
+ Column {
+ spacing : C.style.main.spacing
+ Label {
+ text : qsTr("Store map tiles in")
+ }
+ ButtonRow {
+ checkedButton : mapTiles.storageType == "files" ? filesButton : sqliteButton
+ Button {
+ id : filesButton
+ text : "files"
+ onClicked : mapTiles.storageType = "files"
+ }
+ Button {
+ id : sqliteButton
+ text : "Sqlite"
+ onClicked : mapTiles.storageType = "sqlite"
+ }
+ }
+ }
+ }
}
-*/
}
|
[-]
[+]
|
Changed |
modrana_0.43.4.tar.gz/modrana/opt/modrana/modules/mod_location/mod_location.py
^
|
@@ -39,7 +39,7 @@
self.set('bearing', None)
self.set('elevation', None)
self.status = "Unknown"
- self.enabled = False
+ self._enabled = False
self.provider = None
self.startSignal = Signal()
self.stopSignal = Signal()
@@ -82,7 +82,7 @@
# only try to update position info if
# location is enabled
- if self.enabled and self.provider:
+ if self._enabled and self.provider:
self.provider._updateGPSD()
fix = self.provider.getFix()
@@ -181,13 +181,13 @@
"""start location - device based or gpsd"""
# send the location start signal
self.startSignal()
- if not self.enabled:
+ if not self._enabled:
print("location: enabling location")
if self.modrana.dmod.handlesLocation():
self.modrana.dmod.startLocation(startMainLoop=startMainLoop)
elif self.provider:
self.provider.start(startMainLoop=startMainLoop)
- self.enabled = True
+ self._enabled = True
else:
print('location: location already enabled')
@@ -202,7 +202,12 @@
# if it is available, stop location
elif self.provider:
self.provider.stop()
- self.enabled = False
+ self._enabled = False
+
+ @property
+ def enabled(self):
+ """Report if location is enabled"""
+ return self._enabled
def shutdown(self):
try:
|
[-]
[+]
|
Changed |
modrana_0.43.4.tar.gz/modrana/opt/modrana/modules/mod_markers.py
^
|
@@ -35,9 +35,18 @@
self.groups = {} # marker groups
def addGroup(self, name, points, menu=False):
- """the name must be unique,
- if it isn't the previous similarly named group is overwritten
- points is a list of point objects"""
+ """Add a marker group
+
+ The name must be unique, if it isn't, the previous
+ group with the same name is overwritten.
+
+ :param name: group name
+ :type name: str
+ :param points: a list of Point instances for the group
+ :type points: list
+ :param menu: if a menu should be generated for the group
+ :type menu: bool
+ """
g = PointGroup(points)
if menu:
g.setMenuEnabled(menu)
@@ -49,9 +58,14 @@
return g
def removeGroup(self, name):
- """remove a group by name
- return True if a group was removed and False if it wasn't due to
- not being found"""
+ """Remove a group by name
+
+ :param name: group name
+ :type name: str
+ :returns: True if a group was removed and False if it
+ wasn't due to not being found
+ :rtype: bool
+ """
if name in self.groups.keys():
del self.groups[name]
return True
@@ -59,18 +73,37 @@
return False
def getGroup(self, name):
+ """Get a group by name
+ :param name: group name
+ :type name: str
+ :returns: a list of groups found or None
+ :rtype: a list or None
+ """
if name in self.groups.keys():
return self.groups[name]
else:
return None
def groupExists(self, name):
- """return if a group with a given name exists"""
+ """Return if a group with a given name exists
+
+ :param name: name of the group
+ :type name: str
+ :returns: True if groups exists False if not
+ :rtype: bool
+ """
return name in self.groups.keys()
def clearAll(self):
+ """Remove all groups"""
self.groups = {}
+ def handleMessage(self, message, messageType, args):
+ if message == "removeGroup":
+ self.removeGroup(args)
+ elif message == "clearAll":
+ self.clearAll()
+
def drawMapOverlay(self, cr):
if self.groups:
pos = self.get('pos', None)
|
[-]
[+]
|
Deleted |
modrana_0.43.4.tar.gz/modrana/opt/modrana/modules/mod_onlineServices/local_search.py
^
|
@@ -1,77 +0,0 @@
-#local search result handling
-
-from core.point import Point
-
-
-class LocalSearchPoint(Point):
- """a local search result point"""
-
- def __init__(self, lat, lon, name="", description="", phoneNumbers=None, urls=None, addressLines=None, emails=None):
- if not emails: emails = []
- if not addressLines: addressLines = []
- if not urls: urls = []
- if not phoneNumbers: phoneNumbers = []
- Point.__init__(self, lat, lon, message=name)
- self._name = name
- self.description = description
- self._message = None
- self.phoneNumbers = phoneNumbers
- self.urls = urls
- self.addressLines = addressLines
- self.emails = emails
-
- def getName(self):
- return self._name
-
- def getDescription(self):
- return self.description
-
- def getMessage(self):
- # lazy message generation
- # = only generate the message once it is requested for the first time
- if self._message is None:
- self.updateMessage()
- return self._message
- else:
- return self._message
-
- def updateMessage(self):
- """call this if you change the properties of an existing point"""
- message = ""
- message += "%s\n\n" % self._name
- if self.description != "":
- message += "%s\n" % self.description
- for item in self.addressLines:
- message += "%s\n" % item
- for item in self.phoneNumbers:
- message += "%s\n" % item[1]
- for item in self.emails:
- message += "%s\n" % item
- for item in self.urls:
- message += "%s\n" % item
- self.setMessage(message)
-
- def __unicode__(self):
- return self.getMessage()
-
-
-class GoogleLocalSearchPoint(LocalSearchPoint):
- def __init__(self, GLSResult):
- # dig the data out of the GLS result
- # and load it to the LSPoint object
- addressLine = "%s, %s, %s" % (GLSResult['streetAddress'], GLSResult['city'], GLSResult['country'])
- phoneNumbers = []
- for number in GLSResult['phoneNumbers']:
- # number types
- # "" -> normal phone number
- # "FAX" -> FAX phone number
- phoneNumbers.append((number['type'], number['number']))
-
- LocalSearchPoint.__init__(
- self,
- lat=float(GLSResult['lat']),
- lon=float(GLSResult['lng']),
- name=GLSResult['titleNoFormatting'],
- addressLines=[addressLine],
- phoneNumbers=phoneNumbers
- )
\ No newline at end of file
|
[-]
[+]
|
Changed |
modrana_0.43.4.tar.gz/modrana/opt/modrana/modules/mod_onlineServices/mod_onlineServices.py
^
|
@@ -18,6 +18,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#---------------------------------------------------------------------------
from core import constants
+from core import point
+from core import threads
from modules.base_module import RanaModule
import traceback
import sys
@@ -44,6 +46,10 @@
self.workerThreads = []
self.drawOverlay = False
self.workStartTimestamp = None
+ self._connectingCondition = threading.Condition()
+ # TODO: move to location ?
+ self._initGPSCondition = threading.Condition()
+
# # testing
# def firstTime(self):
@@ -84,62 +90,21 @@
provider = online_providers.ReverseGeocodingNominatim()
provider.searchAsync(callback, term=searchPoint)
- def localSearch(self, term, where=None, maxResults=8):
+ def localSearch(self, term, around=None, maxResults=8):
"""Synchronous generic local search query
- * if where is not specified, current position is used
- * returns False if the search failed for some reason
+ * if around is not specified, current position is used
"""
# we use the Google Local Search backend at the moment
+ provider = online_providers.GoogleLocalSearch()
+ return provider.search(term=term, around=around, maxResults=maxResults)
- if where is None: # use current position coordinates
- pos = self.get("pos", None)
- if pos is None:
- print("onlineServices: can't do local search - current location unknown")
- return False
- else:
- lat, lon = pos
- local = self.googleLocalQueryLL(term, lat, lon)
- if local:
- points = self._processGLSResponse(local)
- return points
- else:
- return []
- else: # use location description provided in where
- # drop the possible geo prefix
- # as Google Local Search seems not to like it
- if where.startswith('geo:'):
- where = where[4:]
-
- queryString = "%s loc:%s" % (term, where)
- local = self.googleLocalQuery(queryString, maxResults)
- if local:
- points = self._processGLSResponse(local)
- return points
- else:
- return []
-
- def localSearchLL(self, term, lat, lon):
- """Synchronous generic local search query
- * around a point specified by latitude and longitude"""
-
+ def localSearchAsync(self, term, callback, around=None, maxResults=8):
+ provider = online_providers.GoogleLocalSearch()
# we use the Google Local Search backend at the moment
- local = self.googleLocalQueryLL(term, lat, lon)
- if local:
- points = self._processGLSResponse(local)
- return points
- else:
- return []
+ provider.searchAsync(callback, term=term, around=around, maxResults=maxResults)
- def _processGLSResponse(self, response):
- """load GLS results to LocalSearchPoint objects"""
- results = response['responseData']['results']
- points = []
- for result in results:
- point = local_search.GoogleLocalSearchPoint(result)
- points.append(point)
- return points
- # ** OSM static map URL **
+ # ** OSM static map URL **
def getOSMStaticMapUrl(self, centerLat, centerLon, zl, w=350, h=350, defaultMarker="ol-marker", markerList=None):
"""construct & return OSM static map URL"""
@@ -186,58 +151,35 @@
gMap = googlemaps.GoogleMaps(key)
return gMap
- def googleLocalQuery(self, query, maxResults=0):
- print("local search query: %s" % query)
- gMap = self.getGmapsInstance()
- if not maxResults:
- maxResults = int(self.get('GLSResults', 8))
- local = gMap.local_search(query, maxResults)
- return local
-
- def googleLocalQueryLL(self, term, lat, lon):
- query = self.constructGoogleQuery(term, "%f,%f" % (lat, lon))
- local = self.googleLocalQuery(query)
- return local
-
- def constructGoogleQuery(self, term, location):
- """get a correctly formatted GLS query"""
- query = "%s loc:%s" % (term, location)
- return query
-
def _googleReverseGeocode(self, lat, lon):
gMap = self.getGmapsInstance()
address = gMap.latlng_to_address(lat, lon)
return address
- def googleLocalQueryLLAsync(self, term, lat, lon, outputHandler, key):
- """asynchronous Google Local Search query for explicit lat, lon coordinates"""
- location = "%f,%f" % (lat, lon)
- self.googleLocalQueryAsync(term, location, outputHandler, key)
-
- def googleLocalQueryPosAsync(self, term, outputHandler, key):
- """asynchronous Google Local Search query around current position,
- if current position is unknown, wait for locationTimeout seconds before failing"""
- flags = {
- 'GPS': True,
- 'net': True
- }
- self._addWorkerThread(Worker._localGoogleSearch, [term], outputHandler, key, flags)
-
- def googleLocalQueryAsync(self, term, location, outputHandler, key):
- """asynchronous Google Local Search query for """
- print("online: GLS search")
- # TODO: we use a single thread for both routing and search for now, maybe have separate ones ?
- flags = {'net': True}
- self._addWorkerThread(Worker._localGoogleSearch, [term, location], outputHandler, key, flags)
-
# ** Wikipedia search (through Geonames) **
def wikipediaSearch(self, query):
- return geonames.wikipediaSearch(query)
+ """Synchronous Wikipedia search - search for georeferenced Wikipedia
+ articles for the given query
- def wikipediaSearchAsync(self, query, outputHandler, key):
- flags = {'net': True}
- self._addWorkerThread(Worker._onlineWikipediaSearch, [query], outputHandler, key, flags)
+ :param query: Wikipedia search query
+ :type query: str
+ :return: a list of Point instances
+ :rtype: list
+ """
+ return online_providers.WikipediaSearchNominatim().search(term=query)
+
+ def wikipediaSearchAsync(self, query, callback):
+ """Asynchronous Wikipedia search - search for georeferenced Wikipedia
+ articles for the given query
+
+ :param query: Wikipedia search query
+ :type query: str
+ :return: a list of Point instances
+ :rtype: list
+ """
+ provider = online_providers.WikipediaSearchNominatim()
+ provider.searchAsync(callback, term=query)
# ** Background processing **
@@ -327,54 +269,6 @@
def dontReturnResult(self):
self.returnResult = False
- def _locateCurrentPosition(self, locationTimeout=30):
- """try to locate current position and run search when done or time out"""
- self._setWorkStatusText("GPS fix in progress...")
- sleepTime = 0.5 # in seconds
- pos = None
- fix = 0
- startTimestamp = time.time()
- elapsed = 0
- while elapsed < locationTimeout and self.returnResult:
- pos = self.online.get('pos', None)
- fix = self.online.get('fix', 1)
- if fix > 1 and pos:
- break
- time.sleep(sleepTime)
- elapsed = time.time() - startTimestamp
- if fix > 1 and pos: # got GPS fix ?
- return pos
- else: # no GPS lock
- self._notify("failed to get GPS fix", 5000)
- return None
-
- def _checkConnectivity(self):
- """check Internet connectivity - if no Internet connectivity is available, wait for up to 30 seconds
- and then fail (this is used to handle cases where the device was offline and the Internet connection is
- just being established)"""
- status = self.online.modrana.dmod.getInternetConnectivityStatus()
|
[-]
[+]
|
Changed |
modrana_0.43.4.tar.gz/modrana/opt/modrana/modules/mod_onlineServices/online_providers.py
^
|
@@ -1,7 +1,11 @@
# -*- coding: utf-8 -*-
# Online geodata providers
import time
+import re
from core import constants
+from core.point import Point
+from core import requirements
+from modules.mod_onlineServices import geonames
try:
import json
@@ -9,7 +13,6 @@
import simplejson as json
from core.providers import POIProvider, DummyController
-from core.point import Point
try: # Python 2
from urllib import urlencode
@@ -22,11 +25,96 @@
NOMINATIM_GEOCODING_URL = "http://nominatim.openstreetmap.org/search?"
NOMINATIM_REVERSE_GEOCODING_URL = "http://nominatim.openstreetmap.org/reverse?"
+
+#local search result handling
+
+class LocalSearchPoint(Point):
+ """a local search result point"""
+
+ def __init__(self, lat, lon, name="", description="", phoneNumbers=None, urls=None, addressLines=None, emails=None):
+ if not emails: emails = []
+ if not addressLines: addressLines = []
+ if not urls: urls = []
+ if not phoneNumbers: phoneNumbers = []
+ Point.__init__(self, lat, lon, message=name)
+ self._name = name
+ self.description = description
+ self._message = None
+ self._phoneNumbers = phoneNumbers
+ self.urls = urls
+ self._addressLines = addressLines
+ self.emails = emails
+
+ @property
+ def addressLines(self):
+ return self._addressLines
+
+ @property
+ def phoneNumbers(self):
+ return self._phoneNumbers
+
+ def getDescription(self):
+ return self.description
+
+ def getMessage(self):
+ # lazy message generation
+ # = only generate the message once it is requested for the first time
+ if self._message is None:
+ self.updateMessage()
+ return self._message
+ else:
+ return self._message
+
+ def updateMessage(self):
+ """call this if you change the properties of an existing point"""
+ message = ""
+ message += "%s\n\n" % self._name
+ if self.description != "":
+ message += "%s\n" % self.description
+ for item in self._addressLines:
+ message += "%s\n" % item
+ for item in self.phoneNumbers:
+ message += "%s\n" % item[1]
+ for item in self.emails:
+ message += "%s\n" % item
+ for item in self.urls:
+ message += "%s\n" % item
+ self.setMessage(message)
+
+ def __unicode__(self):
+ return self.getMessage()
+
+
+class GoogleLocalSearchPoint(LocalSearchPoint):
+ def __init__(self, GLSResult):
+ # dig the data out of the GLS result
+ # and load it to the LSPoint object
+ addressLine = "%s, %s, %s" % (GLSResult['streetAddress'], GLSResult['city'], GLSResult['country'])
+ phoneNumbers = []
+
+ for number in GLSResult.get('phoneNumbers', []):
+ # number types
+ # "" -> normal phone number
+ # "FAX" -> FAX phone number
+ phoneNumbers.append((number['type'], number['number']))
+
+ LocalSearchPoint.__init__(
+ self,
+ lat=float(GLSResult['lat']),
+ lon=float(GLSResult['lng']),
+ name=GLSResult['titleNoFormatting'],
+ addressLines=[addressLine],
+ phoneNumbers=phoneNumbers
+ )
+
+
class GoogleAddressSearch(POIProvider):
def __init__(self):
POIProvider.__init__(self, threadName=constants.THREAD_ADDRESS_SEARCH)
- def search(self, term=None, around=None, controller=DummyController()):
+ # online geocoding needs Internet access
+ @requirements.internet
+ def search(self, term=None, around=None, controller=DummyController(), **kwargs):
"""Search for an address using Google geocoding API"""
if term is None:
print("online_services: GoogleAddressSearch: term is None")
@@ -35,11 +123,92 @@
controller.status = "online address search done"
+class GoogleLocalSearch(POIProvider):
+ def __init__(self):
+ POIProvider.__init__(self, threadName=constants.THREAD_LOCAL_SEARCH_GOOGLE)
+
+
+ def _constructGLSQuery(self, term, location):
+ """get a correctly formatted GLS query"""
+ # check if the location is a Point or a string
+ if not isinstance(location, str):
+ # convert a Point object to lat,lon string
+ location = "%f,%f" % (location.lat, location.lon)
+
+ query = "%s loc:%s" % (term, location)
+
+ # Local Search doesn't like the geo: prefix so we remove it
+ query = re.sub("loc:.*geo:", "loc:", query)
+
+ return query
+
+ def _processGLSResponse(self, response):
+ """load GLS results to LocalSearchPoint objects"""
+ results = response['responseData']['results']
+ points = []
+ for result in results:
+ point = GoogleLocalSearchPoint(result)
+ points.append(point)
+ return points
+
+ # first check if around is provided and enable GPS if not
+ # as current position "becomes" around
+ @requirements.needsAround
+ # then start Internet and conditionally GPS,
+ # so that they both can be initialized in parallel
+ @requirements.startGPS(conditional=True)
+ @requirements.startInternet
+ # now run the GPS na Internet checks
+ @requirements.gps(conditional=True)
+ @requirements.internet
+ def search(self, term=None, around=None,
+ controller=DummyController(), maxResults=8 ,**kwargs):
+ """Search for POI using Google local search API"""
+ if term is None and around is None:
+ print("online_services: Google local search: term and location not set")
+ return []
+ elif term is None:
+ print("online_services: Google local search: term not set")
+ return []
+ elif around is None:
+ print("online_services: Google local search: location not set")
+ return []
+ controller.status = "online POI search"
+
+ query = self._constructGLSQuery(term, around)
+
+ print("local search query: %s" % query)
+ gMap = _getGmapsInstance()
+ if gMap:
+ result = gMap.local_search(query, maxResults)
+ controller.status = "processing POI from search"
+ points = self._processGLSResponse(result)
+ controller.status = "online POI search done"
+ return points
+ else:
+ print("Google local search: no Google maps instance")
+
+
+def _getGmapsInstance():
+ """get a google maps wrapper instance"""
+ key = constants.GOOGLE_API_KEY
+ if key is None:
+ print("online_providers:"
+ " a google API key is needed for using the Google maps services")
+ return None
+ # only import when actually needed
+ from modules import googlemaps
+ gMap = googlemaps.GoogleMaps(key)
+ return gMap
+
|
[-]
[+]
|
Changed |
modrana_0.43.4.tar.gz/modrana/opt/modrana/modules/mod_route/mod_route.py
^
|
@@ -437,6 +437,13 @@
:param routeParams: parameters for the route search
:type routeParams: RouteParameters object instance or None for defaults
"""
+
+ if routeParams is None:
+ routeParams = self._getDefaultRouteParameters()
+ # no custom route parameters provided, build default ones
+ # based on current settings
+
+
providerID = self.get('routingProvider', "GoogleDirections")
if providerID == "Monav":
# is Monav initialized ? (lazy initialization)
@@ -474,6 +481,26 @@
routeParams=routeParams
)
+
+ def _getDefaultRouteParameters(self):
+ mode = self.get("mode", "car")
+ routeMode = constants.ROUTE_CAR
+ langCode = self.get("directionsLanguage", "en en")
+ # the (Google) language code is the second part of
+ # this whitespace delimited string
+ langCode = langCode.split(" ")[1]
+ if mode == "walk":
+ routeMode = constants.ROUTE_PEDESTRIAN
+ elif mode == "cycle":
+ routeMode = constants.ROUTE_BIKE
+ routeParams = routing_providers.RouteParameters(
+ routeMode=routeMode,
+ avoidTollRoads=self.get("routingAvoidToll", False),
+ avoidHighways=self.get("routingAvoidHighways", False),
+ language = langCode
+ )
+ return routeParams
+
def llRoute(self, start, destination, middlePoints=None):
if not middlePoints: middlePoints = []
@@ -507,7 +534,8 @@
waypoints = [start, destination]
# specify that this route lookup should expect start and destination
# specified as address strings
- params = routing_providers.RouteParameters(addressRoute=True)
+ params = self._getDefaultRouteParameters()
+ params.addressRoute = True
self.routeAsync(self._handleRoutingResultCB, waypoints, routeParams=params)
def doRoute(self, waypoints):
@@ -1214,12 +1242,12 @@
menus.showText(cr, destinationText, x4 + w1 / 20, y4 + 2 * dy + dy / 5, w1 - x4 - (w1 / 20) * 2)
def _geocodeStartAndDestination(self):
- """get the address of start and destination coordinates by using geocoding"""
+ """Get the address of start and destination coordinates by using geocoding"""
onlineModule = self.m.get('onlineServices', None)
- connectivity = (self.modrana.dmod.getInternetConnectivityStatus() in (True, None))
+ connectivity = (self.modrana.dmod.connectivityStatus in (constants.ONLINE, constants.CONNECTIVITY_UNKNOWN))
if connectivity and onlineModule:
# set that address lookups are in progress
- # (this function should be called from "inside" theaddress lookup lock)
+ # (this function should be called from "inside" the address lookup lock)
self._startLookup = True
self._destinationLookup = True
@@ -1266,12 +1294,7 @@
self.text = None
self.set('needRedraw', True)
-
-
-
def shutdown(self):
# stop the Monav server, if running
if self.monav:
- self.monav.stopServer()
-
-
+ self.monav.stopServer()
\ No newline at end of file
|
[-]
[+]
|
Changed |
modrana_0.43.4.tar.gz/modrana/opt/modrana/modules/mod_route/routing_providers.py
^
|
@@ -6,7 +6,6 @@
from core import constants
from core import way
from core.backports import six
-from . import monav_support
try:
import json
@@ -42,7 +41,7 @@
print(e)
traceback.print_exc(file=sys.stdout) # find what went wrong
if result is None: # routing failed for unknown reasons
- return RoutingResult(None, RouteParameters)
+ return RoutingResult(None, routeParams)
if result.type == result.SUCCESS:
# convert the Monav result to a Way object usable
# for turn-by-turn navigation using the instruction
@@ -59,7 +58,7 @@
elif result.type == result.ROUTE_FAILED:
RoutingResult(None, routeParams, constants.ROUTING_ROUTE_FAILED)
else:
- return RoutingResult(None, RouteParameters)
+ return RoutingResult(None, routeParams)
else:
print("route: no Monav routing data - can't route")
RoutingResult(None, routeParams, constants.ROUTING_NO_DATA)
@@ -71,7 +70,7 @@
threadName = constants.THREAD_ROUTING_ONLINE_GOOGLE
RoutingProvider.__init__(self, threadName=threadName)
- def search(self, waypoints, routeParams=None, controller=DummyController()):
+ def search(self, waypoints, routeParams=RouteParameters(), controller=DummyController()):
# check if we have at least 2 points
routingStart = time.time()
if len(waypoints) < 2:
@@ -80,8 +79,6 @@
start = waypoints[0]
destination = waypoints[-1]
inBetweenPoints = waypoints[1:-1]
- if routeParams is None:
- routeParams = RouteParameters()
print("GoogleRouting: routing from %s to %s" % (start, destination))
controller.status = "online routing in progress"
route, returnCode, errorMessage = _googleDirections(start, destination, inBetweenPoints, routeParams)
@@ -127,11 +124,17 @@
if not waypoints: waypoints = []
- otherOptions = ""
- if params.avoidHighways: # optionally avoid highways
- otherOptions += 'h'
- if params.avoidTollRoads: # optionally avoid toll roads
- otherOptions += 't'
+ flagDir = {'language': params.language}
+
+ # toll and highway avoidance options
+ if params.avoidHighways and params.avoidTollRoads:
+ flagDir['avoid'] = 'tolls|highways'
+ elif params.avoidHighways: # optionally avoid highways
+ flagDir['avoid'] = 'highways'
+ elif params.avoidTollRoads: # optionally avoid toll roads
+ flagDir['avoid'] = 'tolls'
+
+ # waypoints
waypointOption = None
if waypoints: # waypoints are a list of Point objects
firstWayPoint = waypoints[0]
@@ -140,25 +143,23 @@
waypointOption += "|%f,%f" % (waypoint.lat, waypoint.lon)
# respect travel mode
- directionsType = ""
+ routeMode = "driving" # car directions are the default
if params.routeMode == constants.ROUTE_BIKE:
- directionsType = "b"
+ routeMode = "bicycling "
elif params.routeMode == constants.ROUTE_PEDESTRIAN:
- directionsType = "w"
+ routeMode = "walking"
+ flagDir['mode'] = routeMode
+
# TODO: check if/how public transport routing works
#elif mode == 'train' or mode == 'bus':
# directionsType = 'r'
#else:
# directionsType = ""
- # combine mode and other parameters
- flagDir = {'language': params.language}
# the google language code is the second part of this whitespace delimited string
#googleLanguageCode = self.get('directionsLanguage', 'en en').split(" ")[1]
gMap = _getGmapsInstance()
- parameters = directionsType + otherOptions
- flagDir['dirflg'] = parameters
if waypointOption:
flagDir['waypoints'] = waypointOption
flagDir['sensor'] = 'false'
|
[-]
[+]
|
Changed |
modrana_0.43.4.tar.gz/modrana/opt/modrana/modules/mod_search.py
^
|
@@ -17,6 +17,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#---------------------------------------------------------------------------
+from core.point import Point
from modules.base_module import RanaModule
from core import geo
import math
@@ -43,6 +44,8 @@
self.where = 'position'
self.menuWatchId = None
self.filters = {}
+ # names of marker groups used for search results
+ self._relatedMarkerGroups = ["addressResults", "wikipediaResults"]
def firstTime(self):
self.menuWatchId = self.modrana.watch('menu', self._checkMenuEnteredCB)
@@ -167,7 +170,12 @@
elif message == 'clearSearch':
self.localSearchResults = None
self.list = None
- self.notify("search results cleared", 2000)
+ # also remove all search related marker groups
+ markers = self.m.get("markers")
+ if markers:
+ for group in self._relatedMarkerGroups:
+ markers.removeGroup(group)
+ self.notify("all search results cleared", 2000)
#TODO: also clear address & Wikipedia search results
elif message == 'storePOI':
store = self.m.get('storePOI', None)
@@ -186,6 +194,8 @@
elif message == 'localSearch':
if messageType == 'ml' and args:
+ query = None
+ location = None
online = self.m.get('onlineServices', None)
if not online:
print("search: online services module not present")
@@ -196,26 +206,24 @@
# parse coordinates
lat = float(args[1])
lon = float(args[2])
+ location = Point(lat, lon)
query = args[3]
- online.googleLocalQueryLLAsync(query, lat, lon, self.handleSearchResult, "localSearchResultGoogle")
elif lsType == "location":
# search around a location (address, coordinates, etc. ),
# modRana just forwards the location to the search engine
location = args[1]
- term = args[2]
- online.googleLocalQueryAsync(term, location, self.handleSearchResult, "localSearchResultGoogle")
+ query = args[2]
elif lsType == "position": # search around current position
query = args[1]
fix = self.get('fix', 0)
pos = self.get('pos', None)
-
if fix > 1 and pos:
lat, lon = pos
- online.googleLocalQueryLLAsync(query, lat, lon, self.handleSearchResult,
- "localSearchResultGoogle")
+ location = Point(lat, lon)
else:
print("search: position unknown - trying to get GPS lock")
- online.googleLocalQueryPosAsync(query, self.handleSearchResult, "localSearchResultGoogle")
+ # location = None will trigger GPS fix attempt (provided GPS is enabled in Options)
+ location = None
elif lsType == "view": #search around current map center
query = args[1]
proj = self.m.get('projection', None)
@@ -223,10 +231,14 @@
centreLL = proj.getScreenCentreLL()
if centreLL:
(lat, lon) = centreLL
- online.googleLocalQueryLLAsync(query, lat, lon, self.handleSearchResult,
- "localSearchResultGoogle")
+ location = Point(lat, lon)
else:
print("search: screen center coordinates unknown")
+ return
+
+ if query:
+ online.localSearchAsync(query, self._handleLocalSearchResultsCB,
+ around=location)
elif message == "search":
if messageType == "ml" and args:
@@ -237,7 +249,7 @@
online = self.m.get('onlineServices', None)
if online:
# geocode the text input asynchronously
- online.geocodeAsync(query, self)
+ online.geocodeAsync(query, self._address2llCB)
else:
print("search: online services module missing")
elif sType == "wikipedia":
@@ -246,14 +258,17 @@
online = self.m.get('onlineServices', None)
if online:
# search Wikipedia asynchronously
- online.wikipediaSearchAsync(query, self.handleSearchResult, "wikipedia")
+ online.wikipediaSearchAsync(query, self._handleWikipediaResultsCB)
else:
print("search: online services module missing")
# DEPRECIATED ?, use the localSearch method
+ # TODO: depreciate this
elif message == 'searchThis': # search for a term in the message string
if messageType == 'ms' and args:
searchTerm = args
+ lat = None
+ lon = None
online = self.m.get('onlineServices', None)
if online is None:
print("search: online services module not present")
@@ -277,8 +292,10 @@
else:
print("search: screen center coordinates unknown")
return
-
- online.googleLocalQueryLLAsync(searchTerm, lat, lon, self.handleSearchResult, "localSearchResultGoogle")
+ if lat and lon:
+ location = Point(lat, lon)
+ online.localSearchAsync(searchTerm, self._handleLocalSearchResultsCB,
+ around=location)
# try:
# searchList = []
@@ -328,8 +345,7 @@
# -> we want to actually got to there :)
activeResultTuple = self.getActiveResultTupple()
activeResult = activeResultTuple[1]
- lat = float(activeResult['lat'])
- lon = float(activeResult['lng'])
+ lat, lon = activeResult.getLL()
# clear any old route and route to the result
self.sendMessage('route:clearRoute|md:route:route:type=pos2ll;toLat=%f;toLon=%f;show=start' % (lat, lon))
@@ -355,11 +371,10 @@
# action += "|set:menu:"
# name = item.getTracklogName().split('/').pop()
- # lat = list[index][1]['lat']
- # lon = list[index][1]['lng']
# action += "|set:searchResultShowLatLon:%s,%s" % (lat,lon)
- name = "%s" % itemList[index][1]['titleNoFormatting']
+ point = itemList[index][1]
+ name = "%s" % point.name
units = self.m.get('units', None)
distanceString = units.km2CurrentUnitString(itemList[index][0], dp=2) # use correct units
@@ -390,16 +405,16 @@
position = self.get("pos", None) # our lat lon coordinates
resultList = []
index = 0
- for item in self.localSearchResults['responseData']['results']: # we iterate over the local search results
+ for point in self.localSearchResults: # we iterate over the local search results
if position is not None:
(lat1, lon1) = position
- (lat2, lon2) = (float(item['lat']), float(item['lng']))
+ (lat2, lon2) = point.getLL()
distance = geo.distance(lat1, lon1, lat2, lon2)
- resultTuple = (distance, item, index)
+ resultTuple = (distance, point, index)
resultList.append(resultTuple) # we pack each result into a tuple with ist distance from us
else:
resultTuple = (
- 0, item, index) # in this case, we dont know our position, so we say the distance is 0
+ 0, point, index) # in this case, we dont know our position, so we say the distance is 0
resultList.append(resultTuple)
index += 1
self.list = resultList
@@ -407,16 +422,6 @@
else:
print("search: error -> distance update on empty results")
- def updateItemDistance(self):
- position = self.get("pos", None) # our lat lon coordinates
- if position is not None:
- (lat1, lon1) = position
- (lat2, lon2) = (float(item['lat']), float(item['lng']))
- distance = geo.distance(lat1, lon1, lat2, lon2)
- else:
- distance = 0 # in this case, we don't know our position, so we say the distance is 0
- return distance
-
def drawMenu(self, cr, menuName, args=None):
if menuName == 'searchResults':
menus = self.m.get("menu", None)
@@ -499,7 +504,7 @@
elif menuName == 'searchCustomQuery':
self.drawSearchCustomQueryMenu(cr)
- def drawGLSResultMenu(self, cr, resultTupple):
+ def drawGLSResultMenu(self, cr, resultTuple):
"""draw an info screen for a Google local search result"""
|
[-]
[+]
|
Changed |
modrana_0.43.4.tar.gz/modrana/opt/modrana/modules/mod_showPOI.py
^
|
@@ -63,11 +63,10 @@
proj = self.m.get('projection', None)
if proj and self.visiblePOI:
for POI in self.visiblePOI:
- id = POI.getId()
+ poiID = POI.getId()
lat = POI.getLat()
lon = POI.getLon()
name = POI.getName()
- description = POI.getDescription()
hidePOICaptionZl = int(self.get("hideMarkerCaptionsBelowZl", 13))
if int(self.get('z', 15)) > hidePOICaptionZl:
distanceString = ""
@@ -113,10 +112,10 @@
# register clickable area
click = self.m.get('clickHandler', None)
if click:
- """ make the POI caption clickable"""
- if id is not None: # new POI have id == None
+ # make the POI caption clickable
+ if poiID is not None: # new POI have id == None
click.registerXYWH(rx, ry - (-rh), rw, -rh,
- "ms:showPOI:setActivePOI:%d|set:menu:showPOI#POIDetail" % id)
+ "ms:showPOI:setActivePOI:%d|set:menu:showPOI#POIDetail" % poiID)
else: # the last added POI is still set, no need to set the id
click.registerXYWH(rx, ry - (-rh), rw, -rh, "set:menu:showPOI#POIDetail")
cr.fill()
@@ -135,8 +134,8 @@
if store and menus:
if message == "setupCategoryList":
if messageType == 'ml':
- """this is used for executing something special instead of going to the POIDetail menu
- after a POI is selected"""
+ # this is used for executing something special instead of going to the POIDetail menu
+ # after a POI is selected
POISelectedAction = args[0]
action = "ml:showPOI:setupPOIList:%s;%s|set:menu:menu#list#POIList" % ("%d", POISelectedAction)
else:
@@ -152,16 +151,21 @@
menus.addListMenu('POICategories', "set:menu:poi", usedCategories)
elif message == 'setupPOIList':
if args:
+ catId = None
+ action = "set:menu:None"
if messageType == 'ms':
catId = int(args)
action = 'set:menu:showPOI#POIDetail' # use the default action
elif messageType == 'ml':
- """if the message is a message list, execute a custom action instead of the default POI detail menu
- TODO: use this even for selecting the POIDetail menu ?"""
+ # if the message is a message list, execute a custom action instead of the default POI detail menu
+ # TODO: use this even for selecting the POIDetail menu ?
print(args)
catId = int(args[0])
action = args[1]
- poiFromCategory = store.getAllPOIFromCategory(catId)
+ if catId is not None:
+ poiFromCategory = store.getAllPOIFromCategory(catId)
+ else:
+ poiFromCategory = []
# convert the output to a listable menu compatible state
i = 0
for item in poiFromCategory:
@@ -177,14 +181,14 @@
self.activePOI = store.getPOI(POIId)
elif messageType == 'ms' and message == 'storePOI':
if args == "manualEntry":
- """add all POI info manually"""
+ # add all POI info manually
entry = self.m.get('textEntry', None)
if entry:
self.activePOI = store.getEmptyPOI() # set a blank POI as active
# start the chain of entry boxes
entry.entryBox(self, 'newName', 'POI name', "")
elif args == "currentPosition":
- """add current position as a new POI"""
+ # add current position as a new POI
entry = self.m.get('textEntry', None)
if entry:
pos = self.get('pos', None)
@@ -204,7 +208,6 @@
elif args == "fromMapDone": # this is after the point has been clicked
with self.expectLock:
if self.expectPoint == True:
- self.expectPoint == False
self.expectPoint = False # disable the registering
proj = self.m.get('projection', None)
lastClick = self.get('lastClickXY', None)
@@ -216,7 +219,7 @@
self.activePOI.setLat(lat, commit=False)
self.activePOI.setLon(lon, commit=False)
# start the entry box chain
- """we misuse the current position chain"""
+ # we misuse the current position chain
entry.entryBox(self, 'newCurrentPositionName', 'POI name', "")
elif messageType == 'ms' and message == 'editActivePOI':
@@ -237,13 +240,13 @@
entry.entryBox(self, 'lon', 'POI Longitude', lon)
elif messageType == 'ml' and message == 'setupPOICategoryChooser':
- """setup a category chooser menu"""
+ # setup a category chooser menu
if args:
(menu, key) = args
self._setupPOICategoryChooser(menu, key)
elif messageType == 'ms' and message == 'setCatAndCommit':
- """selecting the category is the final stage of adding a POI"""
+ # selecting the category is the final stage of adding a POI
if args:
# set the category
catId = int(args)
@@ -256,7 +259,7 @@
self.set('menu', 'showPOI#POIDetail')
elif message == 'checkMenus':
- """check if the POI menus are "dirty" and need to be regenerated"""
+ # check if the POI menus are "dirty" and need to be regenerated
if self.listMenusDirty:
self.sendMessage('showPOI:setupCategoryList')
if self.activePOI:
@@ -268,9 +271,9 @@
self.activePOI.updateToolsMenu()
elif message == 'listMenusDirty':
- """something regarding the POI changed
- ,the menus might not be up to date
- and may need a regen"""
+ # something regarding the POI changed
+ # ,the menus might not be up to date
+ # and may need a regen
self.listMenusDirty = True
elif message == 'askDeleteActivePOI':
@@ -284,15 +287,15 @@
ask.setupAskYesNo(question, yesAction, noAction)
elif message == 'centerOnActivePOI':
- """something regarding the POI changed
- ,the menus might not be up to date
- and may need a regen"""
+ # something regarding the POI changed
+ # ,the menus might not be up to date
+ # and may need a regen"""
self.activePOI.showOnMap()
elif message == 'routeToActivePOI':
- """something regarding the POI changed
- ,the menus might not be up to date
- and may need a regen"""
+ # something regarding the POI changed
+ # ,the menus might not be up to date
+ # and may need a regen"""
self.activePOI.routeFrom('currentPosition')
self.sendMessage('mapView:recentreToPos')
self.makePOIVisible(self.activePOI)
@@ -387,8 +390,8 @@
if visibleIDs:
store = self.m.get('storePOI', None)
if store:
- for id in visibleIDs:
- self._makePOIVisible(store.getPOI(id))
+ for poiID in visibleIDs:
+ self._makePOIVisible(store.getPOI(poiID))
if self.visiblePOI: # enable POI drawing only if some POI vere restored
self.drawPOI()
print("showPOI: %d visible POI restored" % len(self.visiblePOI))
@@ -428,10 +431,9 @@
entry.entryBox(self, 'newLon', 'POI Longitude', "")
elif key == 'newLon':
self.activePOI.setLon(result, commit=False)
- """final step:
- setup the category chooser menu,
- and make sure the POI is committed after a category is chosen
- """
+ # final step:
+ # setup the category chooser menu,
+ # and make sure the POI is committed after a category is chosen
self._setupPOICategoryChooser('showPOI', 'setCatAndCommit')
self.set('menu', 'menu#list#POICategoryChooser')
self.sendMessage('ml:notification:m:Select a category for this POI;3')
|
[-]
[+]
|
Changed |
modrana_0.43.4.tar.gz/modrana/opt/modrana/version.txt
^
|
@@ -1 +1 @@
-V0.43.3 git:998588a
+V0.43.4 git:1215c98
|