Repository: spyder-ide/spyder

Issue:
Check for new conda packages in Anaconda's repos instead of Github
Right now we're looking for new releases only on Github. But this gives a bad UX in Anaconda because they take several days to create new conda packages for Spyder.

So in that case we need to look for new packages (for example) in

https://repo.continuum.io/pkgs/main/win-64/

to only show the update message when new packages are placed there.

@dalthviz, please work on this one.


Discussion:

Resolving patch:
diff --git a/spyder/workers/updates.py b/spyder/workers/updates.py
--- a/spyder/workers/updates.py
+++ b/spyder/workers/updates.py
@@ -6,7 +6,9 @@
 
 # Standard library imports
 import json
+import os
 import ssl
+import sys
 
 # Third party imports
 from qtpy.QtCore import QObject, Signal
@@ -15,6 +17,7 @@
 from spyder import __version__
 from spyder.config.base import _
 from spyder.py3compat import PY3
+from spyder.config.utils import is_anaconda
 from spyder.utils.programs import check_version, is_stable_version
 
 
@@ -27,30 +30,36 @@
 
 class WorkerUpdates(QObject):
     """
-    Worker that checks for releases using the Github API without blocking the
-    Spyder user interface, in case of connections issues.
+    Worker that checks for releases using either the Anaconda
+    default channels or the Github Releases page without
+    blocking the Spyder user interface, in case of connection
+    issues.
     """
     sig_ready = Signal()
 
-    def __init__(self, parent, startup):
+    def __init__(self, parent, startup, version=""):
         QObject.__init__(self)
         self._parent = parent
         self.error = None
         self.latest_release = None
         self.startup = startup
+        self.version = version
 
-    def check_update_available(self, version, releases):
+    def check_update_available(self, version, releases, github=False):
         """Checks if there is an update available.
 
         It takes as parameters the current version of Spyder and a list of
-        valid cleaned releases in chronological order (what github api returns
-        by default). Example: ['2.3.4', '2.3.3' ...]
+        valid cleaned releases in chronological order.
+        Example: ['2.3.2', '2.3.3' ...] or with github ['2.3.4', '2.3.3' ...]
         """
         if is_stable_version(version):
             # Remove non stable versions from the list
             releases = [r for r in releases if is_stable_version(r)]
 
-        latest_release = releases[0]
+        if github:
+            latest_release = releases[0]
+        else:
+            latest_release = releases[-1]
 
         if version.endswith('dev'):
             return (False, latest_release)
@@ -59,7 +68,17 @@ def check_update_available(self, version, releases):
 
     def start(self):
         """Main method of the WorkerUpdates worker"""
-        self.url = 'https://api.github.com/repos/spyder-ide/spyder/releases'
+        if is_anaconda():
+            self.url = 'https://repo.anaconda.com/pkgs/main'
+            if os.name == 'nt':
+                self.url += '/win-64/repodata.json'
+            elif sys.platform == 'darwin':
+                self.url += '/osx-64/repodata.json'
+            else:
+                self.url += '/linux-64/repodata.json'
+        else:
+            self.url = ('https://api.github.com/repos/'
+                        'spyder-ide/spyder/releases')
         self.update_available = False
         self.latest_release = __version__
 
@@ -81,10 +100,22 @@ def start(self):
                     data = data.decode()
 
                 data = json.loads(data)
-                releases = [item['tag_name'].replace('v', '') for item in data]
-                version = __version__
-
-                result = self.check_update_available(version, releases)
+                if not self.version:
+                    self.version = __version__
+
+                if is_anaconda():
+                    releases = []
+                    for item in data['packages']:
+                        if 'spyder' in item and 'spyder-kernels' not in item:
+                            releases.append(item.split('-')[1])
+                    result = self.check_update_available(self.version,
+                                                         releases)
+                else:
+                    releases = [item['tag_name'].replace('v', '')
+                                for item in data]
+                    result = self.check_update_available(self.version,
+                                                         releases,
+                                                         github=True)
                 self.update_available, self.latest_release = result
             except Exception:
                 error_msg = _('Unable to retrieve information.')


Test patch:
diff --git a/spyder/workers/tests/test_update.py b/spyder/workers/tests/test_update.py
new file mode 100644
--- /dev/null
+++ b/spyder/workers/tests/test_update.py
@@ -0,0 +1,34 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright © Spyder Project Contributors
+# Licensed under the terms of the MIT License
+# (see spyder/__init__.py for details)
+
+import pytest
+
+from spyder.utils.programs import check_version
+from spyder.workers.updates import WorkerUpdates
+
+# Max time to wait for the update check
+# (in miliseconds)
+UPDATE_TIMEOUT = 20000
+
+
+def test_update(qtbot):
+    """Test the update checking for a version that needs an update."""
+    worker = WorkerUpdates(None, False, version="1.0.0")
+    worker.start()
+    assert worker.update_available
+    assert check_version("1.0.0", worker.latest_release, '<')
+
+
+def test_not_update(qtbot):
+    """Test the update checking for a version that don't needs an update."""
+    worker = WorkerUpdates(None, False, version="1000.0.0")
+    worker.start()
+    assert not worker.update_available
+    assert not check_version("1000.0.0", worker.latest_release, '<')
+
+
+if __name__ == "__main__":
+    pytest.main()