Merge lp:~elachuni/ubuntu-webcatalog/import-extras into lp:ubuntu-webcatalog

Proposed by Anthony Lenton
Status: Merged
Approved by: Anthony Lenton
Approved revision: 97
Merged at revision: 98
Proposed branch: lp:~elachuni/ubuntu-webcatalog/import-extras
Merge into: lp:ubuntu-webcatalog
Diff against target: 186 lines (+90/-20)
2 files modified
src/webcatalog/management/commands/import_app_install_data.py (+46/-20)
src/webcatalog/tests/test_commands.py (+44/-0)
To merge this branch: bzr merge lp:~elachuni/ubuntu-webcatalog/import-extras
Reviewer Review Type Date Requested Status
Danny Tamez (community) Approve
Review via email: mp+100660@code.launchpad.net

Commit message

Attempt to import icon information from extras.ubuntu.com whenever it's available.

Description of the change

This branch will attempt to import icon information from extras.ubuntu.com whenever it's available.

import_app_install_data will also pull in apps from extras, so that they start appearing within the Apps Directory. I'm still unsure as to how screenshot data should be retrieved, at the moment it'll only be imported if it's available from screenshots.ubuntu.com like other apps from the main repos (that is, screenshots won't be retrieved from MyApps for these apps).

To post a comment you must log in.
Revision history for this message
Danny Tamez (zematynnad) wrote :

Hey Anthony - all looks fine.

review: Approve

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 2012-03-29 21:47:54 +0000
3+++ src/webcatalog/management/commands/import_app_install_data.py 2012-04-03 17:55:23 +0000
4@@ -22,15 +22,17 @@
5 with_statement,
6 )
7
8+import json
9 import os
10-import json
11+import re
12 import shutil
13 import tempfile
14 import urllib
15
16-from urlparse import urljoin
17 from glob import iglob
18 from optparse import make_option
19+from tempfile import NamedTemporaryFile
20+from urlparse import urljoin
21
22 import apt
23 from apt.cache import FetchFailedException
24@@ -56,6 +58,7 @@
25 deb http://archive.ubuntu.com/ubuntu {distroseries} main universe
26 deb http://archive.ubuntu.com/ubuntu {distroseries}-updates main universe
27 deb http://archive.canonical.com/ubuntu {distroseries} partner
28+deb http://extras.ubuntu.com/ubuntu {distroseries} main
29 """
30
31 def __init__(self, distroseries):
32@@ -175,7 +178,7 @@
33
34 self.output("Adding {0} to {1}\n".format(
35 screenshot_url,
36- app.package_name), 1)
37+ app.package_name), 2)
38 app.applicationmedia_set.get_or_create(
39 media_type='screenshot',
40 url=screenshot_url,
41@@ -248,11 +251,7 @@
42 break
43
44 if icon_path:
45- parts = os.path.splitext(icon_path)
46- if parts[1] in ['.xpm', '.svg', '.tiff']:
47- target_path = parts[0] + '.png'
48- if create_png_from_file(target_path, icon_path, 32, 32):
49- icon_path = target_path
50+ icon_path = self.convert_to_png(icon_path)
51 with open(icon_path, "r") as icon_file:
52 app.icon = ImageFile(icon_file)
53 app.save()
54@@ -261,6 +260,34 @@
55 app.name, icon_path_generic,
56 '|'.join(supported_extensions)).encode('utf-8'), 1)
57
58+ def convert_to_png(self, icon_path):
59+ parts = os.path.splitext(icon_path)
60+ if parts[1] in ['.xpm', '.svg', '.tiff']:
61+ target_path = parts[0] + '.png'
62+ if create_png_from_file(target_path, icon_path, 32, 32):
63+ icon_path = target_path
64+ return icon_path
65+
66+ def fetch_icon_from_extras(self, app, candidate):
67+ """Fetch icon from the /meta/ directory on extras.ubuntu.com.
68+
69+ This method will only do anything if the provided app is in extras.
70+ """
71+ icon_name = candidate.record.get('Icon')
72+ match = re.match('http://(.*)extras.ubuntu.com/', candidate.uri)
73+ if icon_name and match:
74+ uri = match.group() + 'meta/' + icon_name
75+ response = urllib.urlopen(uri)
76+ if response.getcode() == 200:
77+ parts = os.path.splitext(icon_name)
78+ with NamedTemporaryFile(suffix=parts[1]) as filep:
79+ filep.write(response.read())
80+ filep.flush()
81+ icon_path = self.convert_to_png(filep.name)
82+ with open(icon_path, "r") as icon_file:
83+ app.icon = ImageFile(icon_file)
84+ app.save()
85+
86 def update_from_cache(self, distroseries_name):
87 distroseries, created = DistroSeries.objects.get_or_create(
88 code_name=distroseries_name)
89@@ -291,18 +318,16 @@
90 version = apt.apt_pkg.upstream_version(candidate.version)
91 if package.name in prefetched_apps:
92 app = prefetched_apps[package.name]
93- if (app.description == candidate.description and
94- app.section == candidate.section and
95- app.name == app_name and
96- app.comment == app_comment):
97- continue
98- app.description = candidate.description
99- app.section = candidate.section
100- app.version = version
101- app.name = app_name
102- app.comment = app_comment
103- app.save()
104-
105+ updated = False
106+ for attribute, value in [
107+ ('description', candidate.description),
108+ ('section', candidate.section), ('version', version),
109+ ('name', app_name), ('comment', app_comment)]:
110+ if getattr(app, attribute) != value:
111+ setattr(app, attribute, value)
112+ updated = True
113+ if updated:
114+ app.save()
115 else:
116 app = Application.objects.create(
117 package_name=package.name,
118@@ -314,6 +339,7 @@
119 comment=app_comment,
120 )
121 self.get_screenshot_urls_from_server(app)
122+ self.fetch_icon_from_extras(app, candidate)
123 if self.verbosity == 1:
124 self.output("\n", 1)
125 return distroseries
126
127=== modified file 'src/webcatalog/tests/test_commands.py'
128--- src/webcatalog/tests/test_commands.py 2012-03-29 21:47:54 +0000
129+++ src/webcatalog/tests/test_commands.py 2012-04-03 17:55:23 +0000
130@@ -363,6 +363,7 @@
131 deb http://archive.ubuntu.com/ubuntu natty main universe
132 deb http://archive.ubuntu.com/ubuntu natty-updates main universe
133 deb http://archive.canonical.com/ubuntu natty partner
134+deb http://extras.ubuntu.com/ubuntu natty main
135 """,
136 sources_list_content)
137 if self.use_mock_apt_cache:
138@@ -522,6 +523,49 @@
139 qs = app.applicationmedia_set.filter(media_type='screenshot')
140 self.assertEqual(2, qs.count())
141
142+ @patch('urllib.urlopen')
143+ def test_fetch_icon_from_extras(self, mock_urlopen):
144+ mock_urlopen.return_value.getcode.return_value = 200
145+ mock_urlopen.return_value.read.return_value = "I'm a png!"
146+ app = self.factory.make_application()
147+ candidate = Mock()
148+ candidate.uri = 'http://extras.ubuntu.com/pool/f/foobar.deb'
149+ candidate.record = {'Icon': 'foo.png'}
150+ command = ImportAppInstallCommand()
151+
152+ command.fetch_icon_from_extras(app, candidate)
153+
154+ self.assertEqual("I'm a png!", app.icon.read())
155+ self.assertEqual(1, mock_urlopen.call_count)
156+ mock_urlopen.assert_called_with(
157+ 'http://extras.ubuntu.com/meta/foo.png')
158+
159+ @patch('urllib.urlopen')
160+ def test_fetches_nothing_if_no_icon(self, mock_urlopen):
161+ app = self.factory.make_application()
162+ candidate = Mock()
163+ candidate.uri = 'http://extras.ubuntu.com/pool/f/foobar.deb'
164+ candidate.record = {}
165+ command = ImportAppInstallCommand()
166+
167+ command.fetch_icon_from_extras(app, candidate)
168+
169+ self.assertEqual(0, mock_urlopen.call_count)
170+ self.assertFalse(app.icon)
171+
172+ @patch('urllib.urlopen')
173+ def test_fetches_nothing_if_not_in_extras(self, mock_urlopen):
174+ app = self.factory.make_application()
175+ candidate = Mock()
176+ candidate.uri = 'http://archive.ubuntu.com/pool/f/foobar.deb'
177+ candidate.record = {'Icon': 'foobar.png'}
178+ command = ImportAppInstallCommand()
179+
180+ command.fetch_icon_from_extras(app, candidate)
181+
182+ self.assertEqual(0, mock_urlopen.call_count)
183+ self.assertFalse(app.icon)
184+
185
186 class ImportRatingsTestCase(TestCaseWithFactory):
187

Subscribers

People subscribed via source and target branches