Skip to content

Commit

Permalink
Basic Offline mode support (bug 107)
Browse files Browse the repository at this point in the history
Detect network connections on Linux (still need to find a way to
implement it for Windows and OS X - on these platforms, this
implementation acts as if the connection is always available).

We might need to use this in more places in the code, but for starters
this should work nicely.

The Linux implementation assumes the "ip" command is available.
  • Loading branch information
thp committed Oct 13, 2012
1 parent a50cb92 commit e3f5360
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 4 deletions.
11 changes: 10 additions & 1 deletion share/gpodder/ui/qml/Main.qml
Expand Up @@ -425,10 +425,19 @@ Image {

Label {
id: messageDialogText
anchors.centerIn: parent
anchors {
left: parent.left
right: parent.right
verticalCenter: parent.verticalCenter
leftMargin: Config.largeSpacing
rightMargin: Config.largeSpacing
}
color: 'white'
font.pixelSize: 20
font.bold: true
width: parent.width
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.WordWrap
}
}

Expand Down
8 changes: 8 additions & 0 deletions src/gpodder/gtkui/main.py
Expand Up @@ -2339,6 +2339,11 @@ def on_btnCancelFeedUpdate_clicked(self, widget):

def update_feed_cache(self, channels=None,
show_new_episodes_dialog=True):
if not util.connection_available():
self.show_message(_('Please connect to a network, then try again.'),
_('No network connection'), important=True)
return

# Fix URLs if mygpo has rewritten them
self.rewrite_urls_mygpo()

Expand Down Expand Up @@ -3319,6 +3324,9 @@ def restart_auto_update_timer(self):
interval, self._on_auto_update_timer)

def _on_auto_update_timer(self):
if not util.connection_available():
logger.debug('Skipping auto update (no connection available)')

logger.debug('Auto update timer fired.')
self.update_feed_cache()

Expand Down
20 changes: 20 additions & 0 deletions src/gpodder/qmlui/__init__.py
Expand Up @@ -474,6 +474,9 @@ def find_episode(self, podcast_url, episode_url):

@Slot()
def updateAllPodcasts(self):
if not self.request_connection():
return

# Process episode actions received from gpodder.net
def merge_proc(self):
self.root.start_progress(_('Merging episode actions...'))
Expand All @@ -497,11 +500,28 @@ def find_episode(podcast_url, episode_url, counter):
if not podcast.pause_subscription:
podcast.qupdate(finished_callback=self.update_subset_stats)

def request_connection(self):
"""Request an internet connection
Returns True if a connection is available, False otherwise
"""
if not util.connection_available():
# TODO: Try to request the network connection dialog, and wait
# for a connection - if a connection is available, return True

self.root.show_message('\n\n'.join((_('No network connection'),
_('Please connect to a network, then try again.'))))
return False

return True

@Slot(int)
def contextMenuResponse(self, index):
assert index < len(self.context_menu_actions)
action = self.context_menu_actions[index]
if action.action == 'update':
if not self.request_connection():
return
podcast = action.target
if not podcast.pause_subscription:
podcast.qupdate(finished_callback=self.update_subset_stats)
Expand Down
42 changes: 39 additions & 3 deletions src/gpodder/util.py
Expand Up @@ -1628,15 +1628,51 @@ def run_in_background(function, daemon=False):
return thread


def website_reachable(url='http://www.google.com'):
def linux_get_active_interfaces():
"""Get active network interfaces using 'ip link'
Returns a list of active network interfaces or an
empty list if the device is offline. The loopback
interface is not included.
"""
stdout = subprocess.check_output(['ip', 'link'])
return re.findall(r'\d+: ([^:]+):.*state UP', stdout)


def connection_available():
"""Check if an Internet connection is available
Returns True if a connection is available (or if there
is no way to determine the connection). Returns False
if no network interfaces are up (i.e. no connectivity).
"""
try:
if gpodder.win32:
# FIXME: Implement for Windows
return True
elif gpodder.osx:
# FIXME: Implement for Mac OS X
return True
else:
return len(linux_get_active_interfaces()) > 0
except Exception, e:
logger.warn('Cannot get connection status: %s', e, exc_info=True)
return False


def website_reachable(url):
"""
Check if a specific website is available.
"""
"""
if not connection_available():
# No network interfaces up - assume website not reachable
return (False, None)

try:
response = urllib2.urlopen(url, timeout=1)
return (True, response)
except urllib2.URLError as err:
pass

return (False, None)

0 comments on commit e3f5360

Please sign in to comment.