Merge lp:~michael.nelson/ubuntu-webcatalog/determine-app-install-version into lp:ubuntu-webcatalog

Proposed by Michael Nelson
Status: Merged
Approved by: Łukasz Czyżykowski
Approved revision: 15
Merged at revision: 11
Proposed branch: lp:~michael.nelson/ubuntu-webcatalog/determine-app-install-version
Merge into: lp:ubuntu-webcatalog
Diff against target: 225 lines (+97/-35)
2 files modified
src/webcatalog/management/commands/import_app_install_data.py (+51/-21)
src/webcatalog/tests/test_commands.py (+46/-14)
To merge this branch: bzr merge lp:~michael.nelson/ubuntu-webcatalog/determine-app-install-version
Reviewer Review Type Date Requested Status
Canonical ISD hackers Pending
Review via email: mp+57721@code.launchpad.net

Commit message

[r=lukasz] Determine most recent app-install-data uri for download for given distroseries.

Description of the change

Overview
========
This branch enables the importer to find the latest app install data for a given distroseries, removing the hard-coded natty package uri.

I was unsure whether to use mocks in the test - it works without the mocks, just takes a while.

Example runs for natty and lucid

michael@devmav:~/isd/webcat/current_work$ fab manage:'import_app_install_data natty'
[localhost] run: virtualenv/bin/python django_project/manage.py import_app_install_data natty
Determining URI for current version of app-install-data in natty.
creating: /tmp/tmpJieAlT/var/lib/dpkg
creating: /tmp/tmpJieAlT/var/cache/apt/archives/partial
creating: /tmp/tmpJieAlT/var/lib/apt/lists/partial
Downloading app-install-data-ubuntu from http://archive.ubuntu.com/ubuntu/pool/main/a/app-install-data-ubuntu/app-install-data_0.11.04.7.1_all.deb...Done.
Processing application data to update database...
No icon found for Eclipse at /tmp/tmpotEAQf/usr/share/app-install/icons/eclipse.(xpm|png|svg|tiff).
Eclipse created.
No icon found for Mah-Jong at /tmp/tmpotEAQf/usr/share/app-install/icons/mah-jong.(xpm|png|svg|tiff).
Mah-Jong created.
No icon found for Personal File Sharing at /tmp/tmpotEAQf/usr/share/app-install/icons/folder-remote.(xpm|png|svg|tiff).
Personal File Sharing created.
No icon found for Advanced Strategic Command at /tmp/tmpotEAQf/usr/share/app-install/icons/asc.(xpm|png|svg|tiff).
Advanced Strategic Command created.
Tangerine Media Sharing created.
^C
Stopped.
michael@devmav:~/isd/webcat/current_work$ fab manage:'import_app_install_data lucid'
[localhost] run: virtualenv/bin/python django_project/manage.py import_app_install_data lucid
Determining URI for current version of app-install-data in lucid.
creating: /tmp/tmpxLr0I8/var/lib/dpkg
creating: /tmp/tmpxLr0I8/var/cache/apt/archives/partial
creating: /tmp/tmpxLr0I8/var/lib/apt/lists/partial
Downloading app-install-data-ubuntu from http://archive.ubuntu.com/ubuntu/pool/main/a/app-install-data-ubuntu/app-install-data_0.10.04.7_all.deb...Done.
Processing application data to update database...
Granatier created.
No icon found for Eclipse at /tmp/tmpBzKAd8/usr/share/app-install/icons/eclipse.(xpm|png|svg|tiff).
Eclipse created.
No icon found for Mah-Jong at /tmp/tmpBzKAd8/usr/share/app-install/icons/mah-jong.(xpm|png|svg|tiff).
Mah-Jong created.
No icon found for KThesaurus at /tmp/tmpBzKAd8/usr/share/app-install/icons/kthesaurus.(xpm|png|svg|tiff).
KThesaurus created.
No icon found for Personal File Sharing at /tmp/tmpBzKAd8/usr/share/app-install/icons/folder-remote.(xpm|png|svg|tiff).
Personal File Sharing created.
No icon found for Advanced Strategic Command at /tmp/tmpBzKAd8/usr/share/app-install/icons/asc.(xpm|png|svg|tiff).
Advanced Strategic Command created.

To post a comment you must log in.
13. By Michael Nelson

stdout tweaks.

14. By Michael Nelson

Ensure we don't call apt.cache during get_latest_app_data_for_series.

15. By Michael Nelson

Removed verbosity as a kwarg for all methods, instead using a class attribute.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/webcatalog/management/commands/import_app_install_data.py'
2--- src/webcatalog/management/commands/import_app_install_data.py 2011-04-13 11:09:59 +0000
3+++ src/webcatalog/management/commands/import_app_install_data.py 2011-04-15 09:19:27 +0000
4@@ -26,13 +26,14 @@
5 import shutil
6 import tempfile
7 import urllib
8-from apt_inst import DebFile
9 from glob import iglob
10 from optparse import make_option
11 from StringIO import StringIO
12
13+import apt
14+from apt_inst import DebFile
15 from django.core.files.images import ImageFile
16-from django.core.management.base import BaseCommand
17+from django.core.management.base import LabelCommand
18
19 from webcatalog.forms import ApplicationForm
20
21@@ -41,34 +42,26 @@
22 ]
23
24
25-class Command(BaseCommand):
26+class Command(LabelCommand):
27
28 help = "Update Application data from app-install-data package."
29- option_list = BaseCommand.option_list + (
30+ option_list = LabelCommand.option_list + (
31 make_option('--local-app-install-deb',
32 action='store',
33 dest='local_app_install_deb',
34 default='',
35 help=('Use a local app-install-data deb package rather than '
36 'downloading from the archive.')),
37- )
38+ )
39+ verbosity = 0
40
41- def handle(self, *args, **options):
42+ def handle_label(self, distroseries, **options):
43 self.verbosity = int(options['verbosity'])
44+ data_dir = tempfile.mkdtemp()
45 # Download app install data when requested.
46 if options['local_app_install_deb'] == '':
47- install_data_url = ("http://archive.ubuntu.com/"
48- "ubuntu/pool/main/a/app-install-data-ubuntu/"
49- "app-install-data_0.11.04.7.1_all.deb")
50- if self.verbosity > 0:
51- self.stdout.write(
52- u"Downloading app-install-data-ubuntu from {0}...".format(
53- install_data_url))
54- tmp_file = tempfile.NamedTemporaryFile()
55- urllib.urlretrieve(install_data_url, tmp_file.name)
56- deb_location = tmp_file.name
57- if self.verbosity > 0:
58- self.stdout.write("Done.\n")
59+ deb_location = self.get_latest_app_data_for_series(
60+ distroseries, working_dir=data_dir)
61 else:
62 deb_location = options['local_app_install_deb']
63
64@@ -77,7 +70,6 @@
65 if self.verbosity > 0:
66 self.stdout.write(
67 "Processing application data to update database...\n")
68- data_dir = tempfile.mkdtemp()
69 deb_file.data.extractall(data_dir)
70 matcher = data_dir + '/usr/share/app-install/desktop/*.desktop'
71 icon_dir = data_dir + '/usr/share/app-install/icons/'
72@@ -86,10 +78,48 @@
73
74 shutil.rmtree(data_dir)
75
76- def get_uri_for_series(self, distro_series):
77+ def get_latest_app_data_for_series(self, distroseries, working_dir):
78 # Write a temporary sources.list, update the cache and access:
79 # cache['app-install-data-ubuntu'].candidate.uri
80- pass
81+ install_data_url = self.get_app_data_uri_for_series(distroseries)
82+ rest, sep, deb_filename = install_data_url.rpartition('/')
83+
84+ if self.verbosity > 0:
85+ self.stdout.write(
86+ u"Downloading app-install-data-ubuntu from {0}...".format(
87+ install_data_url))
88+ deb_location = os.path.join(working_dir, deb_filename)
89+ urllib.urlretrieve(install_data_url, deb_location)
90+ if self.verbosity > 0:
91+ self.stdout.write("Done.\n")
92+ return deb_location
93+
94+ def get_app_data_uri_for_series(self, distroseries):
95+ # Create a temporary apt cache to find the uri for the
96+ # current version in the given series.
97+ if self.verbosity > 0:
98+ self.stdout.write(
99+ "Determining URI for current version of "
100+ "app-install-data in {0}.\n".format(distroseries))
101+
102+ # First we create an appropriate temporary sources.list entry.
103+ tmp_sources_dir = tempfile.mkdtemp()
104+ os.makedirs(os.path.join(tmp_sources_dir, 'etc', 'apt'))
105+ tmp_sources_list = os.path.join(
106+ tmp_sources_dir, 'etc', 'apt', 'sources.list')
107+ sources_list = open(tmp_sources_list, 'w+')
108+ sources_list.write(
109+ 'deb http://archive.ubuntu.com/ubuntu {0} main\n'.format(
110+ distroseries))
111+ sources_list.close()
112+
113+ cache = apt.Cache(rootdir=tmp_sources_dir, memonly=True)
114+ cache.update(sources_list=tmp_sources_list)
115+ cache.open()
116+ uri = cache['app-install-data'].candidate.uri
117+
118+ shutil.rmtree(tmp_sources_dir)
119+ return uri
120
121 def process_desktop_file(self, desktop_file_path, icon_dir):
122 with open(desktop_file_path, 'r') as desktop_file:
123
124=== modified file 'src/webcatalog/tests/test_commands.py'
125--- src/webcatalog/tests/test_commands.py 2011-04-13 17:19:16 +0000
126+++ src/webcatalog/tests/test_commands.py 2011-04-15 09:19:27 +0000
127@@ -26,7 +26,11 @@
128 import tempfile
129
130 from django.core.management import call_command
131-from mock import patch
132+from mock import (
133+ patch,
134+ MagicMock,
135+ Mock,
136+ )
137
138 from webcatalog.models import Application
139 from webcatalog.management.commands.import_app_install_data import Command
140@@ -41,24 +45,36 @@
141 class ImportAppInstallTestCase(TestCaseWithFactory):
142
143 def test_app_data_downloaded_by_default(self):
144+ get_data_fn = ('webcatalog.management.commands.'
145+ 'import_app_install_data.Command.'
146+ 'get_latest_app_data_for_series')
147+ with patch(get_data_fn) as mock_get_data_fn:
148+ mock_get_data_fn.return_value = self.factory.get_test_path(
149+ 'app-install-data-test_all.deb')
150+ call_command('import_app_install_data', 'onion', verbosity=0)
151+
152+ self.assertEqual(1, mock_get_data_fn.call_count)
153+ self.assertEqual(('onion', ), mock_get_data_fn.call_args[0])
154+
155+ def test_get_latest_app_data_for_series(self):
156 # Requested and downloaded from the server.
157- with patch('urllib.urlretrieve') as mock_urlretrieve:
158- with patch('tempfile.NamedTemporaryFile') as mock_named_tmp_file:
159- mock_tmp_file = mock_named_tmp_file.return_value
160- mock_tmp_file.name = self.factory.get_test_path(
161- 'app-install-data-test_all.deb')
162- call_command('import_app_install_data', verbosity=0)
163+ tmp_dir = tempfile.mkdtemp()
164+ get_uri_fn = (
165+ 'webcatalog.management.commands.import_app_install_data.'
166+ 'Command.get_app_data_uri_for_series')
167+ with patch(get_uri_fn) as mock_get_uri:
168+ mock_get_uri.return_value = 'http://example.com/my.deb'
169+ with patch('urllib.urlretrieve') as mock_urlretrieve:
170+ Command().get_latest_app_data_for_series('natty', tmp_dir)
171+ shutil.rmtree(tmp_dir)
172
173 mock_urlretrieve.assert_called_with(
174- ("http://archive.ubuntu.com/"
175- "ubuntu/pool/main/a/app-install-data-ubuntu/"
176- "app-install-data_0.11.04.7.1_all.deb"),
177- self.factory.get_test_path('app-install-data-test_all.deb'))
178+ 'http://example.com/my.deb', os.path.join(tmp_dir, 'my.deb'))
179
180 def test_local_app_install_deb(self):
181 # We don't hit the network when provided a local app-install deb instead.
182 with patch('urllib.urlretrieve') as mock_urlretrieve:
183- call_command('import_app_install_data',
184+ call_command('import_app_install_data', 'natty',
185 local_app_install_deb=self.factory.get_test_path(
186 'app-install-data-test_all.deb'),
187 verbosity=0)
188@@ -69,7 +85,7 @@
189 self.assertEqual(0, Application.objects.count())
190
191 call_command(
192- 'import_app_install_data',
193+ 'import_app_install_data', 'natty',
194 local_app_install_deb=self.factory.get_test_path(
195 'app-install-data-test_all.deb'),
196 verbosity=0)
197@@ -83,7 +99,7 @@
198
199 def test_icon_added_to_model(self):
200 call_command(
201- 'import_app_install_data',
202+ 'import_app_install_data', 'natty',
203 local_app_install_deb=self.factory.get_test_path(
204 'app-install-data-test_all.deb'),
205 verbosity=0)
206@@ -97,3 +113,19 @@
207 self.assertEqual(
208 os.path.getsize(self.factory.get_test_path('scribus.xpm')),
209 scribus.icon.size)
210+
211+ def test_get_app_data_uri_for_series(self):
212+ # Note: you can test this with the real cache by commenting out
213+ # the mocks - it just takes 4-5 seconds or so.
214+ apt_cache = (
215+ 'webcatalog.management.commands.import_app_install_data.'
216+ 'apt.Cache')
217+ with patch(apt_cache) as mock_apt_cache_cls:
218+ mock_cache_item = Mock()
219+ mock_cache_item.candidate.uri = 'http://example.com/my.deb'
220+ mock_cache = MagicMock()
221+ mock_cache.__getitem__.return_value = mock_cache_item
222+ mock_apt_cache_cls.return_value = mock_cache
223+ uri = Command().get_app_data_uri_for_series('natty')
224+
225+ self.assertEqual('http://example.com/my.deb', uri)

Subscribers

People subscribed via source and target branches