~paolorotolo/software-center/fix-for-963309

« back to all changes in this revision

Viewing changes to softwarecenter/db/update.py

  • Committer: Danny Tamez
  • Date: 2012-01-19 16:17:34 UTC
  • mfrom: (2682 trunk)
  • mto: This revision was merged to the branch mainline in revision 2683.
  • Revision ID: danny.tamez@canonical.com-20120119161734-8viwvv83ph9d4kfx
MergeĀ fromĀ trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
import time
27
27
 
28
28
from gi.repository import GObject
 
29
from piston_mini_client import PistonResponseObject
29
30
 
30
31
from softwarecenter.utils import utf8
31
32
 
131
132
    def desktopf(self):
132
133
        """ return the file that the AppInfo comes from """
133
134
 
134
 
class SoftwareCenterAgentParser(AppInfoParserBase):
 
135
class SCAApplicationParser(AppInfoParserBase):
135
136
    """ map the data we get from the software-center-agent """
136
137
 
137
 
    # map from requested key to sca_entry attribute
 
138
    # map from requested key to sca_application attribute
138
139
    MAPPING = { 'Name'       : 'name',
139
140
                'Price'      : 'price',
140
141
                'Package'    : 'package_name',
141
142
                'Categories' : 'categories',
142
143
                'Channel'    : 'channel',
143
 
                'Deb-Line'   : 'deb_line',
144
144
                'Signing-Key-Id' : 'signing_key_id',
145
145
                'License'    : 'license',
146
146
                'Date-Published' : 'date_published',
147
 
                'Purchased-Date' : 'purchase_date',
148
 
                'License-Key' : 'license_key',
149
 
                'License-Key-Path' : 'license_key_path',
150
147
                'PPA'        : 'archive_id',
151
 
                'Icon'       : 'icon',
152
148
                'Screenshot-Url' : 'screenshot_url',
153
149
                'Thumbnail-Url' : 'thumbnail_url',
154
150
                'Video-Url' :  'video_url',
155
151
                'Icon-Url'   : 'icon_url',
156
152
                'Support-Url'   : 'support_url',
 
153
                'Description' : 'Description',
 
154
                'Comment' : 'Comment',
157
155
              }
158
156
 
159
157
    # map from requested key to a static data element
160
158
    STATIC_DATA = { 'Type' : 'Application',
161
159
                  }
162
160
 
163
 
    def __init__(self, sca_entry):
164
 
        self.sca_entry = sca_entry
 
161
    def __init__(self, sca_application):
 
162
        self.sca_application = sca_application
165
163
        self.origin = "software-center-agent"
166
164
        self._apply_exceptions()
 
165
 
167
166
    def _apply_exceptions(self):
168
167
        # for items from the agent, we use the full-size screenshot for
169
168
        # the thumbnail and scale it for display, this is done because
170
169
        # we no longer keep thumbnail versions of screenshots on the server
171
 
        if (hasattr(self.sca_entry, "screenshot_url") and 
172
 
            not hasattr(self.sca_entry, "thumbnail_url")):
173
 
            self.sca_entry.thumbnail_url = self.sca_entry.screenshot_url
174
 
        if hasattr(self.sca_entry, "description"):
175
 
            self.sca_entry.Comment = self.sca_entry.description.split("\n")[0]
176
 
            self.sca_entry.Description = "\n".join(self.sca_entry.description.split("\n")[1:])
 
170
        if (hasattr(self.sca_application, "screenshot_url") and 
 
171
            not hasattr(self.sca_application, "thumbnail_url")):
 
172
            self.sca_application.thumbnail_url = self.sca_application.screenshot_url
 
173
        if hasattr(self.sca_application, "description"):
 
174
            self.sca_application.Comment = self.sca_application.description.split("\n")[0].strip()
 
175
            self.sca_application.Description = "\n".join(
 
176
                self.sca_application.description.split("\n")[1:]).strip()
 
177
        # WARNING: item.name needs to be different than
 
178
        #          the item.name in the DB otherwise the DB
 
179
        #          gets confused about (appname, pkgname) duplication
 
180
        self.sca_application.name = utf8(_("%s (already purchased)")) % utf8(
 
181
            self.sca_application.name)
 
182
 
 
183
        # XXX 2012-01-16 bug=917109
 
184
        # We can remove these work-arounds once the above bug is fixed on
 
185
        # the server. Until then, we fake a channel here and empty category
 
186
        # to make the parser happy. Note: available_apps api call includes
 
187
        # these already, it's just the apps with subscriptions_for_me which
 
188
        # don't currently.
 
189
        self.sca_application.channel = AVAILABLE_FOR_PURCHASE_MAGIC_CHANNEL_NAME
 
190
        if not hasattr(self.sca_application, 'categories'):
 
191
            self.sca_application.categories = ""
 
192
 
177
193
    def get_desktop(self, key, translated=True):
178
194
        if key in self.STATIC_DATA:
179
195
            return self.STATIC_DATA[key]
180
 
        return getattr(self.sca_entry, self._apply_mapping(key))
 
196
        return getattr(self.sca_application, self._apply_mapping(key))
 
197
 
181
198
    def get_desktop_categories(self):
182
199
        try:
183
 
            return ['DEPARTMENT:' + self.sca_entry.department[-1]] + self._get_desktop_list("Categories")
 
200
            return ['DEPARTMENT:' + self.sca_application.department[-1]] + self._get_desktop_list("Categories")
184
201
        except:
185
202
            return self._get_desktop_list("Categories")
 
203
 
186
204
    def has_option_desktop(self, key):
187
205
        return (key in self.STATIC_DATA or
188
 
                hasattr(self.sca_entry, self._apply_mapping(key)))
 
206
                hasattr(self.sca_application, self._apply_mapping(key)))
 
207
 
189
208
    @property
190
209
    def desktopf(self):
191
210
        return self.origin
192
211
 
193
212
 
 
213
class SCAPurchasedApplicationParser(SCAApplicationParser):
 
214
    """A purchased application hase some additional subscription attributes."""
 
215
 
 
216
    def __init__(self, sca_subscription):
 
217
        # The sca_subscription is a PistonResponseObject, whereas any child
 
218
        # objects are normal Python dicts.
 
219
        self.sca_subscription = sca_subscription
 
220
        super(SCAPurchasedApplicationParser, self).__init__(
 
221
            PistonResponseObject.from_dict(sca_subscription.application))
 
222
        self.sca_application.channel = (
 
223
            PURCHASED_NEEDS_REINSTALL_MAGIC_CHANNEL_NAME)
 
224
 
 
225
    SUBSCRIPTION_MAPPING = { 
 
226
        'Deb-Line'   : 'deb_line',
 
227
        'Purchased-Date' : 'purchase_date',
 
228
        'License-Key' : 'license_key',
 
229
        'License-Key-Path' : 'license_key_path',
 
230
        }
 
231
 
 
232
    MAPPING = dict(
 
233
        SCAApplicationParser.MAPPING.items() + SUBSCRIPTION_MAPPING.items())
 
234
 
 
235
    def get_desktop(self, key, translated=True):
 
236
        if self._subscription_has_option_desktop(key):
 
237
            return getattr(self.sca_subscription, self._apply_mapping(key))
 
238
        return super(SCAPurchasedApplicationParser, self).get_desktop(key)
 
239
 
 
240
    def _subscription_has_option_desktop(self, key):
 
241
        return hasattr(
 
242
            self.sca_subscription, self._apply_mapping(key))
 
243
 
 
244
    def has_option_desktop(self, key):
 
245
        subscription_has_option = self._subscription_has_option_desktop(key)
 
246
        application_has_option = super(
 
247
            SCAPurchasedApplicationParser, self).has_option_desktop(key)
 
248
        return subscription_has_option or application_has_option
 
249
 
 
250
 
194
251
class JsonTagSectionParser(AppInfoParserBase):
195
252
 
196
253
    MAPPING = { 'Name'       : 'application_name',
505
562
        #    continue
506
563
        # index the item
507
564
        try:
508
 
            # we fake a channel here
509
 
            item.channel = PURCHASED_NEEDS_REINSTALL_MAGIC_CHANNEL_NAME
510
 
            # and empty category to make the parser happy
511
 
            item.categories = ""
512
 
            # WARNING: item.name needs to be different than
513
 
            #          the item.name in the DB otherwise the DB
514
 
            #          gets confused about (appname, pkgname) duplication
515
 
            item.name = utf8(_("%s (already purchased)")) % utf8(item.name)
516
 
            parser = SoftwareCenterAgentParser(item)
 
565
            parser = SCAPurchasedApplicationParser(item)
517
566
            index_app_info_from_parser(parser, db_purchased, cache)
518
567
        except Exception as e:
519
568
            LOG.exception("error processing: %s " % e)
560
609
        while context.pending():
561
610
            context.iteration()
562
611
        try:
563
 
            # magic channel
564
 
            entry.channel = AVAILABLE_FOR_PURCHASE_MAGIC_CHANNEL_NAME
565
612
            # now the normal parser
566
 
            parser = SoftwareCenterAgentParser(entry)
 
613
            parser = SCAApplicationParser(entry)
567
614
            index_app_info_from_parser(parser, db, cache)
568
615
        except Exception as e:
569
616
            LOG.warning("error processing: %s " % e)
663
710
        # date published
664
711
        if parser.has_option_desktop("X-AppInstall-Date-Published"):
665
712
            date_published = parser.get_desktop("X-AppInstall-Date-Published")
666
 
            # strip the subseconds from the end of the published date string
667
 
            date_published = str(date_published).split(".")[0]
668
 
            doc.add_value(XapianValues.DATE_PUBLISHED,
669
 
                          date_published)
670
 
            # we use the date published value for the cataloged time as well
671
 
            if "catalogedtime" in axi_values:
672
 
                LOG.debug(
673
 
                        ("pkgname: %s, date_published cataloged time is: %s" %
674
 
                             (pkgname, parser.get_desktop("date_published"))))
675
 
                date_published_sec = time.mktime(
676
 
                                        time.strptime(date_published,
677
 
                                                      "%Y-%m-%d  %H:%M:%S"))
678
 
                doc.add_value(axi_values["catalogedtime"], 
679
 
                              xapian.sortable_serialise(date_published_sec))
 
713
            if date_published:
 
714
                # strip the subseconds from the end of the published date string
 
715
                date_published = str(date_published).split(".")[0]
 
716
                doc.add_value(XapianValues.DATE_PUBLISHED,
 
717
                              date_published)
 
718
                # we use the date published value for the cataloged time as well
 
719
                if "catalogedtime" in axi_values:
 
720
                    LOG.debug(
 
721
                            ("pkgname: %s, date_published cataloged time is: %s" %
 
722
                                 (pkgname, parser.get_desktop("date_published"))))
 
723
                    date_published_sec = time.mktime(
 
724
                                            time.strptime(date_published,
 
725
                                                          "%Y-%m-%d  %H:%M:%S"))
 
726
                    doc.add_value(axi_values["catalogedtime"], 
 
727
                                  xapian.sortable_serialise(date_published_sec))
680
728
        # purchased date
681
729
        if parser.has_option_desktop("X-AppInstall-Purchased-Date"):
682
730
            date = parser.get_desktop("X-AppInstall-Purchased-Date")