rpms/codeina/devel codeina-f8-wishlist.patch, NONE, 1.1 codeina.spec, 1.4, 1.5 codeina-python-dirs.patch, 1.1, NONE

Bastien Nocera (hadess) fedora-extras-commits at redhat.com
Sun Sep 30 23:26:12 UTC 2007


Author: hadess

Update of /cvs/pkgs/rpms/codeina/devel
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv19098

Modified Files:
	codeina.spec 
Added Files:
	codeina-f8-wishlist.patch 
Removed Files:
	codeina-python-dirs.patch 
Log Message:
* Mon Oct 01 2007 - Bastien Nocera <bnocera at redhat.com> - 0.10.1-2
- Big patch from myself (fixes from Thomas) to:
- Show a title to the price column (#299251)
- Not redownload already downloaded packages, and check whether corrupted
  (#305421)
- Select free matching codecs by default (#305411)
- Clearly show an empty list and a warning when no codecs match the required
  ones, so users don't get confused


codeina-f8-wishlist.patch:

--- NEW FILE codeina-f8-wishlist.patch ---
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 827)
+++ ChangeLog	(working copy)
@@ -1,3 +1,24 @@
+2007-09-29  Thomas Vander Stichele  <thomas at apestaart dot org>
+
+	patch by: Bastien Nocera
+
+	* codeina/httpdownload.py:
+	* codeina/listview.py:
+	* codeina/main.py:
+	* codeina/productlist.py:
+	* codeina/requiredplugin.py:
+	* data/available-plugins.xml.in:
+	  Add sha1sums to plugins, and use it to verify plugin download.
+	  See https://bugzilla.redhat.com/show_bug.cgi?id=305421
+	  Add price column header.
+	  See https://bugzilla.redhat.com/show_bug.cgi?id=299251
+	  Select free and matching codecs by default.
+	  See https://bugzilla.redhat.com/show_bug.cgi?id=305411
+	  Don't silently switch to the "all available" view when requesting a
+	  plugin that's not available, instead, show an empty list, and
+	  error
+	  message with an explanation on how to see all the plugins
+
 === release 0.10.1 ===
 
 2007-08-27  Thomas Vander Stichele  <thomas at apestaart dot org>
Index: codeina/requiredplugin.py
===================================================================
--- codeina/requiredplugin.py	(revision 827)
+++ codeina/requiredplugin.py	(working copy)
@@ -51,6 +51,10 @@
                     if self.req_type in self.valid_req_types:
                         self.valid = True
 
+    def __repr__(self):
+        return "<%s for %s> " % (self.__class__.__name__, self.req_string)
+
+
   # currently we're only interested in specialising mp3, we should probably
   # do something more generic later that covers other common formats too
     def is_mp3_decoder(self):
Index: codeina/listview.py
===================================================================
--- codeina/listview.py	(revision 827)
+++ codeina/listview.py	(working copy)
@@ -35,6 +35,10 @@
 
 
 class ListView(gtk.VBox):
+    """
+    @ivar productlist: list of products, set when creating the listview
+    @type productlist: L{codeina.productlist.ProductList}
+    """
 
     def __init__(self):
         gtk.VBox.__init__(self)
@@ -53,7 +57,9 @@
         self.view = gtk.TreeView()
         row_height = self.get_estimated_row_height()
         row_padding = 2  # assumed, random number
-        self.view.set_size_request(-1, (row_height + row_padding) * 8)
+        headers_height = 12 # assumed
+        self.view.set_size_request(-1,
+            (row_height + row_padding) * 8 + headers_height)
         self.productlist = None
         self.store = gtk.ListStore(object)
         self.store.set_default_sort_func(self.sort_func, self)
@@ -61,9 +67,8 @@
         self.model = self.store.filter_new()
         self.model.set_visible_func(self.visible_func, self)
         self.view.set_model(self.model)
-        self.view.set_headers_visible(False)
         self.view.set_rules_hint(True)
-        column = gtk.TreeViewColumn("product")
+        column = gtk.TreeViewColumn(_("Product"))
         text_renderer = gtk.CellRendererText()
         text_renderer.set_property('xpad', 6)
         text_renderer.set_property('ypad', 3)
@@ -79,7 +84,7 @@
       # the expand property to False, so that things behave right if the
       # user makes the window wider
 
-        column = gtk.TreeViewColumn('install-status')
+        column = gtk.TreeViewColumn(_('Installed?'))
         status_renderer = gtk.CellRendererText()
         column.pack_start(status_renderer, True)
         status_renderer.set_property('xalign', 0.5)
@@ -90,7 +95,7 @@
         column.set_expand(False)
         self.view.append_column(column)
 
-        column = gtk.TreeViewColumn('price')
+        column = gtk.TreeViewColumn(_('Price'))
         price_renderer = gtk.CellRendererText()
         column.pack_end(price_renderer, False)
         price_renderer.set_property('xalign', 1.0)
@@ -102,7 +107,7 @@
 
      # Put check boxes in separate column for nicer activation
 
-        column = gtk.TreeViewColumn("toggle")
+        column = gtk.TreeViewColumn("")
         toggle_renderer = gtk.CellRendererToggle()
         toggle_renderer.set_property('activatable', True)
         toggle_renderer.connect('toggled', self.cell_toggled_cb, self)
@@ -145,13 +150,16 @@
             return False
         flav = product.get_best_flavor_for_current_system()
         if not flav:
+            print "product %r does not have flavor" % product
             product.set_selected(False)
             return False
         if not self.required_plugins:
             return True
         else:
+            print "Checking visibility of product %r" % product
             for req in self.required_plugins:
                 if product.provides_requirement(req):
+                    print "provides requirement %r, showing" % req
                     return True
             return False
 
@@ -229,7 +237,7 @@
                              data):
         product = tree_model.get_value(tree_iter, 0)
         if product.price:
-            renderer.set_property('text', "%.0f€" % product.price)
+            renderer.set_property('text', "%.0f €" % product.price)
         else:
             renderer.set_property('text', _("Free"))
         return
@@ -238,11 +246,16 @@
         self.store.clear()
         if self.productlist:
             for p in self.productlist.products:
+                print "appending product %r" % p
                 row = self.store.append()
                 self.store.set_value(row, 0, p)
         return
 
     def set_product_list(self, product_list):
+        """
+        @ivar productlist: list of products the view should handle
+        @type productlist: L{codeina.productlist.ProductList}
+        """
         if self.productlist != product_list:
             self.productlist = product_list
             self.fill_with_products()
Index: codeina/httpdownload.py
===================================================================
--- codeina/httpdownload.py	(revision 827)
+++ codeina/httpdownload.py	(working copy)
@@ -31,7 +31,9 @@
 import thread
 import urllib2
 import xdg.BaseDirectory
+import sha
 
+from codeina.extern.log import log
 from gettext import gettext as _
 
 # Defaults to ~/.local/share/codeina/downloads/ in most cases
@@ -43,7 +45,7 @@
 Downloads a HTTP URI to file in a separate thread and iterates the
 GLib/Gtk main context until either the download is done or an error occurred
 """
-class HttpDownload:
+class HttpDownload(log.Loggable):
     """
     @ivar  content_length: size in bytes of the download
     """
@@ -59,6 +61,7 @@
 
     def __init__ (self):
         self.url = None
+        self.sha1sum = None
         self.directory = None
         self.fn = None
         self.done = False
@@ -71,7 +74,7 @@
     def get_error_msg_from_error(self, err):
         msg = _("Unexpected error of type %s") % type(err)
         try:
-            raise err        
+            raise err
         except urllib2.HTTPError, e:
             if e.code == 403:
               msg = _("Access to this file is forbidden")
@@ -105,7 +108,11 @@
         return msg
 
     """ Iterates the default GLib main context until the download is done """
-    def run(self, url, directory, fn, message=None):
+    def run(self, url, directory, fn, sha1sum, message=None):
+        self.debug("Running download for %s (sha1sum=%s)" % (os.path.join(directory, fn), sha1sum))
+        if sha1sum and self.verify(os.path.join(directory, fn), sha1sum):
+            self.debug("Already downloaded %s" % os.path.join(directory, fn))
+            return None
 
         if self.url:
             return _("Download already in progress")
@@ -116,6 +123,7 @@
         self.url = url
         self.directory = directory
         self.fn = fn
+        self.sha1sum = sha1sum
         self.done = False
         self.err = None
         self.bytes_read = -1
@@ -165,6 +173,23 @@
 
         return not self.done
 
+    """ Check whether a file matches the SHA1 sum given """
+    def verify(self, fn, sha1sum):
+        if not sha1sum:
+            self.debug("No sha1sum or filename, can't check (%s), "
+                "so assuming true" % fn)
+            return True
+
+        fs = open(fn,'rb').read()
+        real_sha1sum = sha.new(fs).hexdigest()
+        if real_sha1sum == sha1sum:
+            self.debug("%s matched its sha1sum" % fn)
+            return True
+
+        self.debug("%s didn't match its sha1sum (got %s expected %s)" % (
+            fn, real_sha1sum, sha1sum))
+        return False
+
     """ Thread where all the downloading and file writing happens """
     def thread_func(self):
 
@@ -191,8 +216,8 @@
                 pass
 
           # Now create a temp file there
-            tmpfile_handle, tmpfile_path = tempfile.mkstemp('.incomplete',\
-                                                            'codeina-download',\
+            tmpfile_handle, tmpfile_path = tempfile.mkstemp('.incomplete',
+                                                            'codeina-download',
                                                             self.directory)
 
             while not self.cancelled:
@@ -211,6 +236,12 @@
                     os.remove(tmpfile_path)
                 except:
                     pass
+            elif not self.verify(tmpfile_path, self.sha1sum):
+                try:
+                    os.remove(tmpfile_path)
+                except:
+                    pass
+                err = _("Downloaded file is corrupted")
             else:
                 os.rename(tmpfile_path, os.path.join(self.directory, self.fn))
 
@@ -277,11 +308,11 @@
     def destroy(self):
         self.dlg.destroy()
 
-    def run(self, url, directory, fn, message):
+    def run(self, url, directory, fn, sha1sum, message):
         if message:
             self.set_dialog_text(message)
         self.dlg.present()
-        err = HttpDownload.run(self, url, directory, fn, None)
+        err = HttpDownload.run(self, url, directory, fn, sha1sum, None)
         self.dlg.hide()
         return err
 
@@ -310,11 +341,16 @@
 
 
 if __name__ == "__main__":
-  # Different URLs for different errors
+    log.init('CODEINA_DEBUG')
+    log.setPackageScrubList('codeina')
+
+    # Different URLs for different errors
     #url='http://shop.fluendo.com/images/mpeg.png'
     #url='http://shop.fluendo.com/tpm-codeina-test.bz2'
     #url='http://example.com/gimme-a-404'
-    url='http://antihost.atari/tpm-codeina-test.bz2'
+    #url='http://antihost.atari/tpm-codeina-test.bz2'
+    url="http://shop.fluendo.com/pub/fluendo-mp3-2.i386.tar.bz2"
+    sha1sum='117f85e118dab2d9f7c9bb10554fbc4e8f7fdf38'
 
     download_dir = DEFAULT_DOWNLOAD_DIR
 
@@ -322,7 +358,7 @@
 
   # Do the downloading, with dialog
     d = HttpDownloadDialog()
-    e = d.run(url, download_dir, fn, "Downloading '%s'" % fn)
+    e = d.run(url, download_dir, fn, sha1sum, "Downloading '%s'" % fn)
     if d.cancelled:
         print "Download cancelled"
     elif e:
Index: codeina/productlist.py
===================================================================
--- codeina/productlist.py	(revision 827)
+++ codeina/productlist.py	(working copy)
@@ -103,13 +103,19 @@
         d['summary'] = self._get_localized(summaries)
         d['flavors'] = flavors
         product = Product(**d)
+
+        # Select the free-not-fully-installed plugins by default
+        if price == 0.0:
+            product.selected = not product.is_fully_installed()
+
         return product
 
     def _parse_flavor(self, node):
         d = {}
         required = ('system', 'arch', 'distro', 'distro-version',
             'core-req', 'base-req', 'last-modified', 'uri', 'comment')
-        attrs = self.parseAttributes(node, required=required)
+        optional = ('sha1sum',)
+        attrs = self.parseAttributes(node, required=required, optional=optional)
         for i in range(0, len(required)):
             # pesky - -> _ translation for attributes
             key = '_'.join(required[i].split('-'))
@@ -125,7 +131,6 @@
         flavor = ProductFlavor(**d)
         return flavor
 
-
     def _parse_name(self, node):
         # parse a name and its language
         # return tuple of language, name
@@ -204,6 +209,9 @@
 
     selected = False # for list view
 
+    def __repr__(self):
+        return "<%s for %s> " % (self.__class__.__name__, self.name)
+
     def get_selected(self):
         return self.selected
 
@@ -398,6 +406,7 @@
     version = None
     uri = None
     comment = None
+    sha1sum = None
 
     def is_compatible(self, system, arch, distro, core_version,
                       base_version):
@@ -418,18 +427,22 @@
 
 
 if __name__ == "__main__":
-    plist = ProductList()
-    try:
-        plist.read_from_xml(open("available-plugins.xml").read())
-        print "done, %d products:" % len(plist.products)
-        for p in plist.products:
-            print " * %s (%.2f EUR)" % (p.name, p.price)
-            for f in p.flavors:
-                print "     - %s %s %s" % (f.system, f.arch, f.distro)
-    except:
-        print "oops, couldn't parse products XML list"
+    xml_data = open("../data/available-plugins.xml")
+    parser = ProductListParser()
+    plist = parser.parse(xml_data)
+    print "done, %d products:" % len(plist.products)
+    for p in plist.products:
+        print " * %s (%.2f EUR)" % (p.name, p.price)
+        for f in p.flavors:
+            print "     - %s %s %s %s %s" % (f.system, f.arch, f.distro, os.path.basename(f.uri), f.sha1sum)
 
-#  flavs = plist.products[0].find_compatible_flavors ("Linux", "ppc64", None, Version("0.10.9"), Version ("0.10.9"))
-#  print "Matching flavors:"
-#  for f in flavs:
-#    print " - %s %s %s %s" % (f.product.name, f.system, f.arch, f.distro)
+    f = plist.products[9].get_best_flavor_for_current_system()
+    print "Best flavor:"
+    print " - %s %s %s %s %s" % (f.system, f.arch, f.distro, os.path.basename(f.uri), f.sha1sum)
+
+    flavs = plist.products[9].find_compatible_flavors ("Linux", "i386", None, check.Version("0.10.4"), check.Version("0.10.4"))
+#    flavs = plist.products[0].find_compatible_flavors ("Linux", "ppc64", None, Version("0.10.9"), Version ("0.10.9"))
+    print "Matching flavors:"
+    for f in flavs:
+        print " - %s %s %s %s %s" % (f.system, f.arch, f.distro, os.path.basename(f.uri), f.sha1sum)
+
Index: codeina/main.py
===================================================================
--- codeina/main.py	(revision 827)
+++ codeina/main.py	(working copy)
@@ -241,6 +241,18 @@
 
         self.vbox.pack_start(self.listview, True)
 
+      # The label showing we have no matching plugins
+
+        self.no_plugins_box = gtk.HBox()
+        img = gtk.Image()
+        img.set_from_stock(gtk.STOCK_DIALOG_WARNING, gtk.ICON_SIZE_DIALOG)
+        self.no_plugins_box.pack_start(img, False, 0, 6)
+        label = gtk.Label(
+            _("There are no plugins available for the requested functionality.")
+            + "\n" + _("Please select the full plugins list in the View menu."))
+        self.no_plugins_box.pack_start(label, False)
+        self.vbox.pack_start(self.no_plugins_box, False)
+
       # status bar
 
         self.statusbar = gtk.Statusbar()
@@ -248,13 +260,15 @@
         self.statusbar.show()
         self.vbox.pack_end(self.statusbar, False)
 
-      # only show matching plugin packages if there are required plugins (?)
+      # only show matching plugin packages if there are required plugins
 
         if self.required_plugins and len(self.required_plugins) > 0:
+            self.debug("Showing the matching plugins list")
             self.actiongroup.get_action('ViewMatching').set_active(True)
         else:
+            self.debug("Showing all the plugins")
             self.actiongroup.get_action('ViewAllAvailable').set_active(True)
-            self.actiongroup.get_action('ViewMatching').set_visible(False)
+            self.actiongroup.get_action('ViewMatching').set_sensitive(False)
 
       # button box
 
@@ -341,7 +355,7 @@
         button.set_property('can-default', True)
         return button
 
-    def download_uri(self, dialog, name, uri):
+    def download_uri(self, dialog, name, uri, sha1sum):
         """
         Download the given uri.
 
@@ -352,7 +366,8 @@
         self.debug("Trying to download '%s'" % uri)
         dl_dir = DEFAULT_DOWNLOAD_DIR
         fn = os.path.basename(uri)
-        err_msg = dialog.run(uri, dl_dir, fn, _("Downloading '%s'") % name)
+        err_msg = dialog.run(uri, dl_dir, fn, sha1sum,
+            _("Downloading '%s'") % name)
         if dialog.cancelled:
             self.debug("Download cancelled")
             return None
@@ -378,7 +393,7 @@
 
         Returns: whether the EULA was accepted.
         """
-        path = self.download_uri(dialog, name, eula_uri)
+        path = self.download_uri(dialog, name, eula_uri, None)
         if not path:
             self.debug('Could not download EULA')
             return False
@@ -412,7 +427,10 @@
                     continue
 
             flavor = p.get_best_flavor_for_current_system()
-            path = self.download_uri(d, p.name, flavor.uri)
+            self.debug("Selected flavour %s %s %s %s %s" % (
+                flavor.system, flavor.arch, flavor.distro,
+                os.path.basename(flavor.uri), flavor.sha1sum))
+            path = self.download_uri(d, p.name, flavor.uri, flavor.sha1sum)
 
             if not path:
                 self.debug('User cancelled')
@@ -513,8 +531,12 @@
             self.listview.show_matching(self.required_plugins)
             no_rows_txt = _(
                 'No matching plugins available for your system yet.')
+
         if self.listview.get_visible_rows() == 0:
             self.set_status_text(no_rows_txt)
+            self.no_plugins_box.show_all()
+        else:
+            self.no_plugins_box.hide()
 
     def do_install(self, filenames):
         failed_installs = []
Index: data/available-plugins.xml.in
===================================================================
--- data/available-plugins.xml.in	(revision 827)
+++ data/available-plugins.xml.in	(working copy)
@@ -50,13 +50,15 @@
                     core-req="0.10.3" base-req="0.10.3"
                     last-modified="2007-05-25"
                     uri="http://shop.fluendo.com/pub/fluendo-mp3-2.i386.tar.bz2"
-                    comment="Tested on FC3, FC4, FC5, and Ubuntu 6.10 (edgy)"
+		    comment="Tested on FC3, FC4, FC5, and Ubuntu 6.10 (edgy)"
+		    sha1sum="117f85e118dab2d9f7c9bb10554fbc4e8f7fdf38"
     />
     <flavor system="Linux" arch="x86_64" distro="generic" distro-version="any"
                     core-req="0.10.3" base-req="0.10.3"
                     last-modified="2007-05-25"
                     uri="http://shop.fluendo.com/pub/fluendo-mp3-2.x86_64.tar.bz2"
-                    comment=""
+		    comment=""
+		    sha1sum="47e2169453c4025e88edd6e4e1b64da26cbf64c6"
     />
   </product>
 


Index: codeina.spec
===================================================================
RCS file: /cvs/pkgs/rpms/codeina/devel/codeina.spec,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- codeina.spec	27 Aug 2007 15:17:49 -0000	1.4
+++ codeina.spec	30 Sep 2007 23:25:40 -0000	1.5
@@ -6,7 +6,7 @@
 
 Name:           codeina
 Version:        0.10.1
-Release:        1%{?dist}
+Release:        2%{?dist}
 Summary:        GStreamer Codec Installation Application
 
 Group:          Applications/Internet
@@ -15,6 +15,7 @@
 # Upstream SVN repository is at https://core.fluendo.com/gstreamer/svn/codeina/trunk/
 Source:         http://www.fluendo.com/downloads/codeina/%{name}-%{version}.tar.bz2
 Source1:        gst-install-plugins-helper.sh
+Patch0:         codeina-f8-wishlist.patch
 BuildRoot:      %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
 
 Requires:       python >= 2.3
@@ -35,6 +36,7 @@
 
 %prep
 %setup -q
+%patch0 -p0 -b .old
 
 %build
 %configure
@@ -62,6 +64,15 @@
 %{_datadir}/%{name}/
 
 %changelog
+* Mon Oct 01 2007 - Bastien Nocera <bnocera at redhat.com> - 0.10.1-2
+- Big patch from myself (fixes from Thomas) to:
+- Show a title to the price column (#299251)
+- Not redownload already downloaded packages, and check whether corrupted
+  (#305421)
+- Select free matching codecs by default (#305411)
+- Clearly show an empty list and a warning when no codecs match the required
+  ones, so users don't get confused
+
 * Mon Aug 27 2007 Thomas Vander Stichele <thomas at apestaart dot org>
 - 0.10.1-1
 - New release


--- codeina-python-dirs.patch DELETED ---




More information about the fedora-extras-commits mailing list