Merge lp:~maclin.jun/ubuntu-kylin-software-center/ubuntu-kylin-software-center into lp:~ubuntukylin-members/ubuntu-kylin-software-center/trunk

Proposed by Ma Jun
Status: Merged
Merged at revision: 12
Proposed branch: lp:~maclin.jun/ubuntu-kylin-software-center/ubuntu-kylin-software-center
Merge into: lp:~ubuntukylin-members/ubuntu-kylin-software-center/trunk
Diff against target: 21119 lines (+6590/-5454)
104 files modified
ReadMe (+16/-0)
advance/__init__.py (+0/-2)
advance/rnrclient_pristine.py (+0/-195)
advance/ukscagent.py (+0/-350)
backend/__init__.py (+18/-2)
backend/aptdaemon/conf/com.ubuntukylin.softwarecenter.conf (+21/-0)
backend/aptdaemon/conf/com.ubuntukylin.softwarecenter.policy (+25/-0)
backend/aptdaemon/conf/com.ubuntukylin.softwarecenter.service (+4/-0)
backend/aptdaemon/dbus_service/__init__.py (+1/-0)
backend/aptdaemon/dbus_service/apt_daemon.py (+301/-0)
backend/aptdaemon/dbus_service/apt_dbus_service.py (+215/-0)
backend/aptdaemon/dbus_service/start_systemdbus.py (+47/-0)
backend/aptdaemon/install.sh (+35/-0)
backend/backend_apt.py (+0/-216)
backend/backend_worker.py (+0/-36)
backend/ibackend.py (+0/-13)
backend/installbackend.py (+149/-0)
backend/piston/rnrclient_pristine.py (+195/-0)
backend/reviewratingspawn.py (+483/-0)
backend/server.py (+0/-53)
backend/sourcelist_apt.py (+0/-3)
backend/ubuntu_sw.py (+128/-0)
data/__init__.py (+5/-6)
data/category/devel (+139/-0)
data/category/game (+410/-0)
data/category/graphic (+86/-0)
data/category/internet (+217/-0)
data/category/multimedia (+249/-0)
data/category/office (+77/-0)
data/category/other (+544/-0)
data/category/profession (+184/-0)
data/category/recommend (+4/-0)
data/category/ubuntukylin (+4/-0)
data/db.py (+0/-7)
do (+0/-3)
model/__init__.py (+0/-3)
model/advertisement.py (+0/-16)
model/software.py (+0/-86)
models/__init__.py (+18/-0)
models/advertisement.py (+46/-0)
models/application.py (+151/-0)
models/appmanager.py (+396/-0)
models/category.py (+105/-0)
models/enums.py (+114/-0)
models/globals.py (+31/-0)
remote/__init__.py (+0/-2)
res/category/devel (+0/-139)
res/category/game (+0/-410)
res/category/graphic (+0/-86)
res/category/internet (+0/-215)
res/category/multimedia (+0/-249)
res/category/office (+0/-77)
res/category/other (+0/-543)
res/category/profession (+0/-184)
res/category/ubuntukylin (+0/-4)
res/windows (+0/-5)
run (+0/-2)
service/__init__.py (+0/-3)
service/software_bo.py (+0/-80)
softwarecenter.py (+834/-0)
test/__init__.py (+0/-2)
test/appmanager_test.py (+32/-0)
test/aptdaemontest.py (+0/-47)
test/apttest.py (+0/-259)
test/duotaitest.py (+0/-19)
test/main.py (+0/-628)
test/miniuitest.py (+0/-69)
test/miniuitest2.py (+0/-38)
test/mysqltest.py (+0/-18)
test/pipetest.py (+0/-24)
test/polkittest.py (+0/-50)
test/signaltest.py (+0/-46)
test/sizetest.py (+0/-14)
test/software_center.py (+0/-644)
test/software_center_test.py (+0/-205)
test/softwarecenter.py (+645/-0)
test/test.py (+50/-0)
test/threadtest.py (+0/-34)
test/uitest.py (+0/-172)
ubuntukylin-softwarecenter.sh (+3/-0)
ui/adwidget.py (+29/-6)
ui/detailscrollwidget.py (+3/-0)
ui/detailw.py (+2/-2)
ui/listitemwidget.py (+61/-21)
ui/mainwindow.py (+11/-3)
ui/recommenditem.py (+45/-13)
ui/tasklistitemwidget.py (+45/-0)
ui/taskw.py (+47/-0)
ui/taskw.ui (+55/-0)
ui/ukliw.py (+23/-0)
ui/ukrcmdw.py (+22/-0)
ui/uksc.py (+22/-0)
ui/uktliw.py (+55/-0)
ui/uktliw.ui (+81/-0)
user/__init__.py (+0/-2)
util/__init__.py (+0/-2)
util/async_process.py (+0/-21)
util/async_thread.py (+0/-27)
util/check_software_thread.py (+0/-51)
util/log.py (+0/-32)
util/vfs.py (+0/-15)
utils/__init__.py (+18/-0)
utils/log.py (+52/-0)
utils/vfs.py (+37/-0)
To merge this branch: bzr merge lp:~maclin.jun/ubuntu-kylin-software-center/ubuntu-kylin-software-center
Reviewer Review Type Date Requested Status
Shine Huang Approve
Review via email: mp+210044@code.launchpad.net

Description of the change

we have merge the works of maclin and shine

To post a comment you must log in.
Revision history for this message
Shine Huang (shine) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'ReadMe'
2--- ReadMe 1970-01-01 00:00:00 +0000
3+++ ReadMe 2014-03-08 03:45:16 +0000
4@@ -0,0 +1,16 @@
5+
6+
7+###############
8+Application management interfaces
9+open_cache
10+get_category_list
11+get_category_byname
12+get_category_apps
13+get_application_by_name
14+get_recommend_apps
15+get_ubuntukylin_apps
16+get_toprated_apps
17+get_review_rating_stats
18+get_application_reviews
19+get_application_screenshots
20+
21
22=== removed directory 'advance'
23=== removed file 'advance/__init__.py'
24--- advance/__init__.py 2014-02-27 08:08:12 +0000
25+++ advance/__init__.py 1970-01-01 00:00:00 +0000
26@@ -1,2 +0,0 @@
27-#!/usr/bin/python
28-__author__ = 'Shine Huang'
29
30=== removed file 'advance/rnrclient_pristine.py'
31--- advance/rnrclient_pristine.py 2014-02-27 08:08:12 +0000
32+++ advance/rnrclient_pristine.py 1970-01-01 00:00:00 +0000
33@@ -1,195 +0,0 @@
34-"""This module provides the RatingsAndReviewsAPI class for talking to the
35-ratings and reviews API, plus a few helper classes.
36-"""
37-
38-from urllib import quote_plus
39-from piston_mini_client import (
40- PistonAPI,
41- PistonResponseObject,
42- PistonSerializable,
43- returns,
44- returns_json,
45- returns_list_of,
46- )
47-from piston_mini_client.validators import validate_pattern, validate
48-#import pdb
49-
50-# These are factored out as constants for if you need to work against a
51-# server that doesn't support both schemes (like http-only dev servers)
52-PUBLIC_API_SCHEME = 'http'
53-AUTHENTICATED_API_SCHEME = 'https'
54-
55-
56-class ReviewRequest(PistonSerializable):
57- """A review request.
58-
59- Instantiate one of these objects to describe a new review you wish to
60- submit, then pass it in as an argument to submit_review().
61- """
62- _atts = ('app_name', 'package_name', 'summary', 'version', 'review_text',
63- 'rating', 'language', 'origin', 'distroseries', 'arch_tag')
64- app_name = ''
65-
66-
67-class ReviewsStats(PistonResponseObject):
68- """A ratings summary for a package/app.
69-
70- This class will be automatically populated with JSON retrieved from the
71- server. Each ReviewStats object will have the following fields:
72- * package_name
73- * app_name
74- * ratings_total
75- * ratings_average
76- """
77- pass
78-
79-
80-class ReviewDetails(PistonResponseObject):
81- """A detailed review description.
82-
83- This class will be automatically populated with JSON retrieved from the
84- server. Each ReviewDetails object will have the following fields:
85- * id
86- * package_name
87- * app_name
88- * language
89- * date_created
90- * rating
91- * reviewer_username
92- * summary
93- * review_text
94- * hide
95- * version
96- """
97- pass
98-
99-
100-class RatingsAndReviewsAPI(PistonAPI):
101- """A client for talking to the reviews and ratings API.
102-
103- If you pass no arguments into the constructor it will try to connect to
104- localhost:8000 so you probably want to at least pass in the
105- ``service_root`` constructor argument.
106- """
107- default_service_root = 'http://localhost:8000/reviews/api/1.0'
108- default_content_type = 'application/x-www-form-urlencoded'
109-
110- @returns_json
111- def server_status(self):
112- """Check the state of the server, to see if everything's ok."""
113- return self._get('server-status/', scheme=PUBLIC_API_SCHEME)
114-
115- @validate_pattern('origin', r'[0-9a-z+-.:/]+', required=False)
116- @validate_pattern('distroseries', r'\w+', required=False)
117- @validate('days', int, required=False)
118- @returns_list_of(ReviewsStats)
119- def review_stats(self, origin='any', distroseries='any', days=None,
120- valid_days=(1, 3, 7)):
121- """Fetch ratings for a particular distroseries"""
122- url = 'review-stats/{0}/{1}/'.format(origin, distroseries)
123- if days is not None:
124- # the server only knows valid_days (1,3,7) currently
125- for valid_day in valid_days:
126- # pick the day from valid_days that is the next bigger than
127- # days
128- if days <= valid_day:
129- url += 'updates-last-{0}-days/'.format(valid_day)
130- break
131- return self._get(url, scheme=PUBLIC_API_SCHEME)
132-
133- @validate_pattern('language', r'\w+', required=False)
134- @validate_pattern('origin', r'[0-9a-z+-.:/]+', required=False)
135- @validate_pattern('distroseries', r'\w+', required=False)
136- @validate_pattern('version', r'[-\w+.:~]+', required=False)
137- @validate_pattern('packagename', r'[a-z0-9.+-]+')
138- @validate('appname', str, required=False)
139- @validate('page', int, required=False)
140- @validate('sort', str, required=False)
141- @returns_list_of(ReviewDetails)
142- def get_reviews(self, packagename, language='any', origin='any',
143- distroseries='any', version='any', appname='', page=1, sort='helpful'):
144- """Fetch ratings and reviews for a particular package name.
145-
146- If any of the optional arguments are provided, fetch reviews for that
147- particular app, language, origin, distroseries or version.
148- """
149- # pdb.set_trace()
150- if appname:
151- appname = quote_plus(';' + appname)
152- return self._get('reviews/filter/%s/%s/%s/%s/%s%s/page/%s/%s/' % (
153- language, origin, distroseries, version, packagename,
154- appname, page, sort),
155- scheme=PUBLIC_API_SCHEME)
156-
157- @validate('review_id', int)
158- @returns(ReviewDetails)
159- def get_review(self, review_id):
160- """Fetch a particular review via its id."""
161- return self._get('reviews/%s/' % review_id)
162-
163- @validate('review', ReviewRequest)
164- @returns(ReviewDetails)
165- def submit_review(self, review):
166- """Submit a rating/review."""
167- return self._post('reviews/', data=review,
168- scheme=AUTHENTICATED_API_SCHEME, content_type='application/json')
169-
170- @validate('review_id', int)
171- @validate_pattern('reason', r'[^\n]+')
172- @validate_pattern('text', r'[^\n]+')
173- @returns_json
174- def flag_review(self, review_id, reason, text):
175- """Flag a review as being inappropriate"""
176- data = {'reason': reason,
177- 'text': text,
178- }
179- return self._post('reviews/%s/flags/' % review_id, data=data,
180- scheme=AUTHENTICATED_API_SCHEME)
181-
182- @validate('review_id', int)
183- @validate_pattern('useful', 'True|False')
184- @returns_json
185- def submit_usefulness(self, review_id, useful):
186- """Submit a usefulness vote."""
187- return self._post('/reviews/%s/recommendations/' % review_id,
188- data={'useful': useful}, scheme=AUTHENTICATED_API_SCHEME)
189-
190- @validate('review_id', int, required=False)
191- @validate_pattern('username', r'[^\n]+', required=False)
192- @returns_json
193- def get_usefulness(self, review_id=None, username=None):
194- """Get a list of usefulness filtered by username/review_id"""
195- if not username and not review_id:
196- return None
197-
198- data = {}
199-
200- if username:
201- data['username'] = username
202- if review_id:
203- data['review_id'] = str(review_id)
204-
205- return self._get('usefulness/', args=data,
206- scheme=PUBLIC_API_SCHEME)
207-
208- @validate('review_id', int)
209- @returns_json
210- def delete_review(self, review_id):
211- """Delete a review"""
212- return self._post('/reviews/delete/%s/' % review_id, data={},
213- scheme=AUTHENTICATED_API_SCHEME)
214-
215- @validate('review_id', int)
216- @validate('rating', int)
217- @validate_pattern('summary', r'[^\n]+')
218- @validate('review_text', str)
219- @returns(ReviewDetails)
220- def modify_review(self, review_id, rating, summary, review_text):
221- """Modify an existing review"""
222- data = {
223- 'rating': rating,
224- 'summary': summary,
225- 'review_text': review_text
226- }
227- return self._put('/reviews/modify/%s/' % review_id, data=data,
228- scheme=AUTHENTICATED_API_SCHEME)
229
230=== removed file 'advance/ukscagent.py'
231--- advance/ukscagent.py 2014-02-28 07:51:15 +0000
232+++ advance/ukscagent.py 1970-01-01 00:00:00 +0000
233@@ -1,350 +0,0 @@
234-# Copyright (C) 2014 Ubuntu Kylin
235-#
236-# Authors:
237-# maclin(majun@ubuntukylin.com)
238-#
239-# This program is free software; you can redistribute it and/or modify it under
240-# the terms of the GNU General Public License as published by the Free Software
241-# Foundation; version 3.
242-#
243-# This program is distributed in the hope that it will be useful, but WITHOUT
244-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
245-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
246-# details.
247-#
248-# You should have received a copy of the GNU General Public License along with
249-# this program; if not, write to the Free Software Foundation, Inc.,
250-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
251-
252-import sys
253-import os
254-import pdb
255-import time
256-
257-from string import join
258-
259-from rnrclient_pristine import RatingsAndReviewsAPI
260-RatingsAndReviewsAPI.default_service_root = "http://reviews.ubuntu.com/reviews/api/1.0"
261-
262-from piston_mini_client import APIError
263-import httplib2
264-import pickle
265-
266-from gettext import gettext as _
267-
268-
269- # reviews
270- #REVIEWS_SERVER = (os.environ.get("SOFTWARE_CENTER_REVIEWS_HOST") or
271- # "http://reviews.ubuntu.com/reviews/api/1.0")
272- #REVIEWS_URL = (REVIEWS_SERVER + "/reviews/filter/%(language)s/%(origin)s/"
273- # "%(distroseries)s/%(version)s/%(pkgname)s%(appname)s/")
274-
275-#=============================================================================begin
276-#Added from softwarecenter.enums
277-# sorting
278-class SortMethods:
279- (UNSORTED,
280- BY_ALPHABET,
281- BY_SEARCH_RANKING,
282- BY_CATALOGED_TIME,
283- BY_TOP_RATED,
284- ) = range(5)
285-
286-
287-class ReviewSortMethods:
288- REVIEW_SORT_METHODS = ['helpful', 'newest']
289- REVIEW_SORT_LIST_ENTRIES = [_('Most helpful first'), _('Newest first')]
290-#=============================================================================end
291-
292-#=============================================================================begin
293-#Added from softwarecenter.backend.reviews.__init__
294-#Modified:
295-# replace app with pkgname
296-# remove classmethod from_json
297-class Review(object):
298- """A individual review object """
299- def __init__(self, pkgname):
300- # a softwarecenter.db.database.Application object
301-# self.app = app
302-# self.app_name = app.appname
303- self.package_name = pkgname
304- # the review items that the object fills in
305- self.id = None
306- self.language = None
307- self.summary = ""
308- self.review_text = ""
309- self.package_version = None
310- self.date_created = None
311- self.rating = None
312- self.reviewer_username = None
313- self.reviewer_displayname = None
314- self.version = ""
315- self.usefulness_total = 0
316- self.usefulness_favorable = 0
317- # this will be set if tryint to submit usefulness for this review
318- # failed
319- self.usefulness_submit_error = False
320- self.delete_error = False
321- self.modify_error = False
322-
323- def __repr__(self):
324- return "[Review id=%s review_text='%s' reviewer_username='%s']" % (
325- self.id, self.review_text, self.reviewer_username)
326-
327- def __cmp__(self, other):
328- # first compare version, high version number first
329- vc = upstream_version_compare(self.version, other.version)
330- if vc != 0:
331- return vc
332- # then wilson score
333- uc = cmp(wilson_score(self.usefulness_favorable,
334- self.usefulness_total),
335- wilson_score(other.usefulness_favorable,
336- other.usefulness_total))
337- if uc != 0:
338- return uc
339- # last is date
340- t1 = datetime.datetime.strptime(self.date_created, '%Y-%m-%d %H:%M:%S')
341- t2 = datetime.datetime.strptime(other.date_created,
342- '%Y-%m-%d %H:%M:%S')
343- return cmp(t1, t2)
344-
345- @classmethod
346- def from_piston_mini_client(cls, other):
347- """ converts the rnrclieent reviews we get into
348- "our" Review object (we need this as we have more
349- attributes then the rnrclient review object)
350- """
351- pkgname = other.package_name
352- review = cls(pkgname)
353- for (attr, value) in other.__dict__.items():
354- if not attr.startswith("_"):
355- setattr(review, attr, value)
356- return review
357-
358-#=============================================================================end
359-
360-#=============================================================================begin
361-#Added from softwarecenter.paths
362-from xdg import BaseDirectory as xdg
363-if "SOFTWARE_CENTER_FAKE_REVIEW_API" in os.environ:
364- SOFTWARE_CENTER_CONFIG_DIR = os.path.join(
365- xdg.xdg_config_home, "software-center", "fake-review")
366- SOFTWARE_CENTER_CACHE_DIR = os.path.join(
367- xdg.xdg_cache_home, "software-center", "fake-review")
368-else:
369- SOFTWARE_CENTER_CONFIG_DIR = os.path.join(
370- xdg.xdg_config_home, "software-center")
371- SOFTWARE_CENTER_CACHE_DIR = os.path.join(
372- xdg.xdg_cache_home, "software-center")
373-#=============================================================================end
374-
375-
376-from gi.repository import GObject
377-
378-import multiprocessing
379-class SpawnProcess(GObject.GObject,multiprocessing.Process):
380- __gsignals__ = {
381- "data-available": (GObject.SIGNAL_RUN_LAST,
382- GObject.TYPE_NONE,
383- (GObject.TYPE_PYOBJECT,),
384- ),
385- }
386-
387- def __init__(self,kwargs=None):
388- super(SpawnProcess, self).__init__()
389- multiprocessing.Process.__init__(self)
390- self.kwargs = kwargs
391- print "\nEnter __init__ of SpawnThread..."
392-
393- def run(self):
394- print "\nEnter run of SpawnThread..."
395-
396- cachedir = os.path.join(SOFTWARE_CENTER_CACHE_DIR, "rnrclient")
397- print cachedir
398- rnrclient = RatingsAndReviewsAPI(cachedir=cachedir) #????
399-
400-#get_reviews(self, packagename, language='any', origin='any', distroseries='any', version='any', appname='', page=1, sort='helpful'):
401-
402- piston_reviews = []
403- try:
404- piston_reviews = rnrclient.get_reviews(packagename="gimp",language='zh_CN')
405- except ValueError as e:
406- print("failed to parse '%s'" % e)
407- #bug lp:709408 - don't print 404 errors as traceback when api request
408- # returns 404 error
409- except APIError as e:
410- print("_get_reviews_threaded: no reviews able to be retrieved for package: %s (%s, origin: %s)" % (options.pkgname, options.distroseries, options.origin))
411- print("_get_reviews_threaded: no reviews able to be retrieved: %s" % e)
412- except httplib2.ServerNotFoundError:
413- # switch to offline mode and try again
414- rnrclient._offline_mode = True
415- piston_reviews = rnrclient.get_reviews(packagename="gimp")
416- except:
417- print("get_reviews*****")
418- sys.exit(1)
419-
420- if piston_reviews is None:
421- piston_reviews = []
422-
423-# for review in piston_reviews:
424-# print("rating: %s user=%s" % (review.rating,
425-# review.reviewer_username))
426-# print(review.summary)
427-# print(review.review_text)
428-# print("\n")
429-
430-
431- res_reviews = join(["%s: %s" % (r.reviewer_username,
432- r.summary)
433- for r in piston_reviews])
434-
435- self.emit("data-available",piston_reviews)
436-
437- print res_reviews
438-
439- # useful for debugging
440- if True:
441- print "\n".join(["%s: %s" % (r.reviewer_username,
442- r.summary)
443- for r in piston_reviews])
444- else:
445- # print to stdout where its consumed by the parent
446- try:
447- print pickle.dumps(piston_reviews)
448- except IOError:
449- # this can happen if the parent gets killed, no need to trigger
450- # apport for this
451- pass
452-
453-
454-class RatingsAndReviewsAgent:
455-
456- def __init__(self):
457-
458- self.language = 'any'
459- self.origin = 'any'
460- self.sort_method = ReviewSortMethods.REVIEW_SORT_METHODS[0] #set default method
461- self.distroseries = 'any'
462-
463- self._reviews = {}
464-
465- def _on_test(self, spawn_helper, piston_reviews):
466- print "\nEnter _on_test..."
467- print piston_reviews
468-
469- def start_get_reviews(self, str_pkgname='gimp', callback=None, page=1):
470- """ public api, triggers fetching a review and calls callback
471- when its ready
472- """
473- #old parameters:translated_app, callback, page=1, language=None, sort=0, relaxed=False
474- language = self.language
475- origin = self.origin
476- distroseries = self.distroseries
477- sort_method = self.sort_method
478- version = "any"
479-
480- kwargs = {"language": language,
481- "origin": origin,
482- "distroseries": distroseries,
483- "packagename": str_pkgname,#options.pkgname.split(':')[0], #multiarch..
484- "version": version,
485- "page": page, #int(options.page),
486- "sort" : sort_method,
487- }
488-
489- spawn_helper = SpawnProcess(kwargs)
490- spawn_helper.connect("data-available", self._on_reviews_ready, str_pkgname, callback)
491- spawn_helper.start()
492-
493- def _on_reviews_ready(self, spawn_helper, piston_reviews, str_pkgname,
494- callback):
495- # convert into our review objects
496- print "\nEnter rnrclient_uk.py, on_reviews_helper_data"
497- reviews = []
498- for r in piston_reviews:
499- reviews.append(Review.from_piston_mini_client(r))
500- # add to our dicts and run callback
501- self._reviews[str_pkgname] = reviews
502- if callback:
503- callback(str_pkgname, self._reviews[str_pkgname])
504- return False
505-
506- def get_reviews(self, str_pkgname='gimp', callback=None, page=1):
507-
508- import urllib
509-
510- # force stdout to be utf-8
511- import codecs
512- sys.stdout = codecs.getwriter('utf8')(sys.stdout)
513-
514- # dump all reviews
515- rnr = RatingsAndReviewsAPI(service_root="http://reviews.ubuntu.com/reviews/api/1.0")
516-
517- sat_res = []
518- sat_res = rnr.server_status()
519- print sat_res
520-
521- res = rnr.review_stats()
522-
523- print len(res)
524-
525- # dump all reviews
526- for stat in res:
527- print("stats for (pkg='%s', app: '%s'): avg=%s total=%s" % (
528- stat.package_name, stat.app_name, stat.ratings_average,
529- stat.ratings_total))
530- reviews = rnr.get_reviews(
531- language="zh_CN", origin="ubuntu", distroseries="precise",
532- packagename=stat.package_name,
533- appname=urllib.quote_plus(stat.app_name.encode("utf-8")))
534-
535- for review in reviews:
536- print("rating: %s user=%s" % (review.rating,
537- review.reviewer_username))
538- print(review.summary)
539- print(review.review_text)
540- print("\n")
541-
542- # get individual ones
543- reviews = rnr.get_reviews(language="zh_CN", origin="ubuntu",
544- distroseries="maverick", packagename="unace", appname="ACE")
545- print(reviews)
546- print(rnr.get_reviews(language="zh_CN", origin="ubuntu", distroseries="saucy",
547- packagename="aclock.app"))
548- print(rnr.get_reviews(language="zh_CN", origin="ubuntu", distroseries="saucy",
549- packagename="unace", appname="ACE"))
550-
551-
552-
553-def _reviews_ready_callback(str_pkgname, reviews_data, my_votes=None,
554- action=None, single_review=None):
555- print "\n***Enter _reviews_ready_callback..."
556- print str_pkgname
557- for review in reviews_data:
558- print("rating: %s user=%s" % (review.rating,
559- review.reviewer_username))
560- print(review.summary)
561- print(review.review_text)
562- print("\n")
563- print "\n\n"
564-
565-
566-if __name__ == "__main__":
567-
568-
569- test = RatingsAndReviewsAgent()
570- piston_reviews = test.start_get_reviews(str_pkgname='gedit',_reviews_ready_callback)
571-
572-# piston_reviews = test.get_reviews('gimp',_reviews_ready_callback)
573-# print piston_reviews
574-# while True:
575-# print "********"
576-# time.sleep(5)
577-
578-
579-
580-
581-
582-
583-
584
585=== modified file 'backend/__init__.py'
586--- backend/__init__.py 2014-02-27 08:08:12 +0000
587+++ backend/__init__.py 2014-03-08 03:45:16 +0000
588@@ -1,2 +1,18 @@
589-#!/usr/bin/python
590-__author__ = 'Shine Huang'
591+# -*- coding: utf-8 -*
592+# Copyright (C) 2014 Ubuntu Kylin
593+#
594+# Authors:
595+# maclin(majun@ubuntukylin.com)
596+#
597+# This program is free software; you can redistribute it and/or modify it under
598+# the terms of the GNU General Public License as published by the Free Software
599+# Foundation; version 3.
600+#
601+# This program is distributed in the hope that it will be useful, but WITHOUT
602+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
603+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
604+# details.
605+#
606+# You should have received a copy of the GNU General Public License along with
607+# this program; if not, write to the Free Software Foundation, Inc.,
608+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
609
610=== added directory 'backend/aptdaemon'
611=== added directory 'backend/aptdaemon/conf'
612=== added file 'backend/aptdaemon/conf/com.ubuntukylin.softwarecenter.conf'
613--- backend/aptdaemon/conf/com.ubuntukylin.softwarecenter.conf 1970-01-01 00:00:00 +0000
614+++ backend/aptdaemon/conf/com.ubuntukylin.softwarecenter.conf 2014-03-08 03:45:16 +0000
615@@ -0,0 +1,21 @@
616+<?xml version="1.0" encoding="UTF-8"?> <!-- -*- XML -*- -->
617+
618+<!DOCTYPE busconfig PUBLIC
619+ "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
620+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
621+<busconfig>
622+ <!-- Only root can own the service -->
623+ <policy user="root">
624+ <allow own="com.ubuntukylin.softwarecenter"/>
625+ <allow send_interface="com.ubuntukylin.softwarecenter"/>
626+ </policy>
627+
628+ <!-- Allow anyone to invoke methods on the interfaces -->
629+ <policy context="default">
630+ <allow send_interface="com.ubuntukylin.softwarecenter"/>
631+ <allow send_destination="com.ubuntukylin.softwarecenter"
632+ send_interface="org.freedesktop.DBus.Introspectable"/>
633+ <allow send_destination="com.ubuntukylin.softwarecenter"
634+ send_interface="org.freedesktop.DBus.Properties"/>
635+ </policy>
636+</busconfig>
637
638=== added file 'backend/aptdaemon/conf/com.ubuntukylin.softwarecenter.policy'
639--- backend/aptdaemon/conf/com.ubuntukylin.softwarecenter.policy 1970-01-01 00:00:00 +0000
640+++ backend/aptdaemon/conf/com.ubuntukylin.softwarecenter.policy 2014-03-08 03:45:16 +0000
641@@ -0,0 +1,25 @@
642+<?xml version="1.0" encoding="UTF-8"?>
643+<!DOCTYPE policyconfig PUBLIC
644+ "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
645+ "http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
646+<policyconfig>
647+
648+ <vendor>Ubuntu Kylin Software Center</vendor>
649+ <vendor_url>http://ubuntukylin.com</vendor_url>
650+ <icon_name>uksoftwarecenter</icon_name>
651+
652+ <action id="com.ubuntukylin.softwarecenter.action">
653+ <_description>
654+ authorization for package management
655+ </_description>
656+ <_message>
657+ To install/uninstall/update/... the pakcages, you need to authenticate.
658+ </_message>
659+ <defaults>
660+ <allow_any>auth_admin</allow_any>
661+ <allow_inactive>auth_admin</allow_inactive>
662+ <allow_active>auth_admin_keep</allow_active>
663+ </defaults>
664+ </action>
665+
666+</policyconfig>
667
668=== added file 'backend/aptdaemon/conf/com.ubuntukylin.softwarecenter.service'
669--- backend/aptdaemon/conf/com.ubuntukylin.softwarecenter.service 1970-01-01 00:00:00 +0000
670+++ backend/aptdaemon/conf/com.ubuntukylin.softwarecenter.service 2014-03-08 03:45:16 +0000
671@@ -0,0 +1,4 @@
672+[D-BUS Service]
673+Name=com.ubuntukylin.softwarecenter
674+Exec=/usr/bin/ubuntukylin-softwarecenter-daemon.py
675+User=root
676
677=== added directory 'backend/aptdaemon/dbus_service'
678=== added file 'backend/aptdaemon/dbus_service/__init__.py'
679--- backend/aptdaemon/dbus_service/__init__.py 1970-01-01 00:00:00 +0000
680+++ backend/aptdaemon/dbus_service/__init__.py 2014-03-08 03:45:16 +0000
681@@ -0,0 +1,1 @@
682+#!/usr/bin/python
683
684=== added file 'backend/aptdaemon/dbus_service/apt_daemon.py'
685--- backend/aptdaemon/dbus_service/apt_daemon.py 1970-01-01 00:00:00 +0000
686+++ backend/aptdaemon/dbus_service/apt_daemon.py 2014-03-08 03:45:16 +0000
687@@ -0,0 +1,301 @@
688+#!/usr/bin/python
689+# -*- coding: utf-8 -*-
690+
691+### BEGIN LICENSE
692+
693+# Copyright (C) 2013 National University of Defense Technology(NUDT) & Kylin Ltd
694+
695+# Author:
696+# kobe Lee <xiangli@ubuntukylin.com>
697+# maclin <majun@ubuntukylin.com>
698+# Maintainer:
699+# maclin <majun@ubuntukylin.com>
700+
701+# This program is free software: you can redistribute it and/or modify it
702+# under the terms of the GNU General Public License version 3, as published
703+# by the Free Software Foundation.
704+#
705+# This program is distributed in the hope that it will be useful, but
706+# WITHOUT ANY WARRANTY; without even the implied warranties of
707+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
708+# PURPOSE. See the GNU General Public License for more details.
709+#
710+# You should have received a copy of the GNU General Public License along
711+# with this program. If not, see <http://www.gnu.org/licenses/>.
712+
713+### END LICENSE
714+
715+import apt
716+import aptsources.sourceslist
717+import apt.progress.base as apb
718+#import threading
719+
720+class FetchProcess(apb.AcquireProgress):
721+ '''Fetch Process'''
722+ def __init__(self, dbus_service, appname):
723+ apb.AcquireProgress.__init__(self)
724+ self.dbus_service = dbus_service
725+ self.appname = appname
726+
727+ def done(self, item):
728+ print 'all items download finished'
729+ if item is not None:
730+ print "FetchProcess, done, Item:", self.appname,item.shortdesc, item.uri, item.owner
731+ self.dbus_service.software_fetch_signal("down_done", "")
732+
733+ def fail(self, item):
734+ print 'download failed'
735+ self.dbus_service.software_fetch_signal("down_fail", "")
736+
737+ def fetch(self, item):
738+ print 'one item download finished'
739+ if item is not None:
740+ print "FetchProcess, fetch, Item:", self.appname, item.shortdesc, item.uri, item.owner
741+ self.dbus_service.software_fetch_signal("down_fetch", "")
742+
743+ def ims_hit(self, item):
744+ print 'ims_hit'
745+
746+ def media_change(self, media, drive):
747+ print 'media_change'
748+
749+ def pulse(self, owner):
750+
751+ self.dbus_service.software_fetch_signal("down_pulse","download_bytes:" + str(self.current_bytes) + ",total_bytes:" + str(self.total_bytes) + ",download_items:" + str(self.current_items) + ",total_items:" + str(self.total_items))
752+
753+ def start(self):
754+ # Reset all our values.
755+ self.current_bytes = 0.0
756+ self.current_cps = 0.0
757+ self.current_items = 0
758+ self.elapsed_time = 0
759+ self.fetched_bytes = 0.0
760+ self.last_bytes = 0.0
761+ self.total_bytes = 0.0
762+ self.total_items = 0
763+ print 'fetch progress start ...',self.appname,
764+ self.dbus_service.software_fetch_signal("down_start", "")
765+
766+ def stop(self):
767+ print 'fetch progress stop ...'
768+ self.dbus_service.software_fetch_signal("down_stop", "")
769+
770+
771+class AptProcess(apb.InstallProgress):
772+ '''Apt progress'''
773+ def __init__(self, dbus_service, appname):
774+ apb.InstallProgress.__init__(self)
775+ self.dbus_service = dbus_service
776+ self.appname = appname
777+
778+ def conffile(self, current, new):
779+ print 'there is a conffile question'
780+
781+ def error(self, pkg, errormsg):
782+ print "AptProcess, error:", self.appname, pkg, errormsg
783+ self.dbus_service.software_apt_signal("apt_error", "")
784+
785+ def start_update(self):
786+ print 'apt process start work', self.appname
787+ self.dbus_service.software_apt_signal("apt_start", "")
788+
789+ def finish_update(self):
790+ print 'apt process finished', self.appname
791+ self.dbus_service.software_apt_signal("apt_stop", "")
792+
793+ def status_change(self, pkg, percent, status):
794+ print "status_change:", self.appname, pkg
795+ print str(int(percent)) + "% status : " + status
796+ self.dbus_service.software_apt_signal("apt_pulse", "percent:" + str(int(percent)) + ",status:" + status)
797+
798+#class AptDaemon(threading.Thread):
799+class AptDaemon():
800+ def __init__(self, dbus_service):
801+
802+ self.dbus_service = dbus_service
803+ self.cache = apt.Cache()
804+ self.cache.open()
805+
806+ # apt-get update
807+ def apt_get_update(self):
808+ self.cache.update(fetch_progress=FetchProcess(self.dbus_service,""))
809+
810+ # get package by pkgName
811+ def get_pkg_by_name(self, pkgName):
812+ print pkgName
813+ try:
814+ return self.cache[pkgName]
815+ except Exception, e:
816+ print e
817+ return "ERROR"
818+
819+ # install package
820+ def install_pkg(self, pkgName):
821+# self.cache.open()
822+ pkg = self.get_pkg_by_name(pkgName)
823+ pkg.mark_install()
824+
825+ try:
826+ self.cache.commit(FetchProcess(self.dbus_service,pkgName), AptProcess(self.dbus_service,pkgName))
827+ except Exception, e:
828+ print e
829+ print "install err"
830+
831+ # uninstall package
832+ def uninstall_pkg(self, pkgName):
833+ self.cache.open()
834+ pkg = self.get_pkg_by_name(pkgName)
835+ pkg.mark_delete()
836+
837+ try:
838+ self.cache.commit(None, AptProcess(self.dbus_service,pkgName))
839+ except Exception, e:
840+ print e
841+ print "uninstall err"
842+
843+ # update package
844+ def upgrade_pkg(self, pkgName):
845+ self.cache.open()
846+ pkg = self.get_pkg_by_name(pkgName)
847+ pkg.mark_upgrade()
848+
849+ try:
850+ self.cache.commit(FetchProcess(self.dbus_service,pkgName), AptProcess(self.dbus_service,pkgName))
851+ except Exception, e:
852+ print e
853+ print "update err"
854+
855+ # check package status by pkgName, i = installed u = can update n = notinstall
856+ def check_pkg_status(self, pkgName):
857+ self.cache.open()
858+ pkg = self.get_pkg_by_name(pkgName)
859+ if(pkg == "ERROR"):
860+ return "ERROR"
861+ if(pkg.is_installed):
862+ if(pkg.is_upgradable):
863+ return "u"
864+ else:
865+ return "i"
866+ else:
867+ return "n"
868+
869+ # check packages status by pkgNameList, i = installed u = can update n = notinstall
870+ def check_pkgs_status(self, pkgNameList):
871+ self.cache.open()
872+ pkgStatusDict = {}
873+ for pkgName in pkgNameList:
874+ pkg = self.get_pkg_by_name(pkgName)
875+ if(pkg == "ERROR"):
876+ continue
877+ if(pkg.is_installed):
878+ if(pkg.is_upgradable):
879+ pkgStatusDict[pkgName] = "u"
880+ else:
881+ pkgStatusDict[pkgName] = "i"
882+ else:
883+ pkgStatusDict[pkgName] = "n"
884+
885+ return pkgStatusDict
886+
887+ # check packages status by pkgNameList, i = installed u = can update n = notinstall
888+ def check_pkgs_status_rtn_list(self, pkgNameList):
889+ self.cache.open()
890+ pkgStatusList = []
891+ for pkgName in pkgNameList:
892+ pkg = self.get_pkg_by_name(pkgName)
893+ if(pkg == "ERROR"):
894+ continue
895+ if(pkg.is_installed):
896+ if(pkg.is_upgradable):
897+ pkgStatusList.append(pkgName + ":u")
898+ else:
899+ pkgStatusList.append(pkgName + ":i")
900+ else:
901+ pkgStatusList.append(pkgName + ":n")
902+
903+ self.dbus_service.software_check_status_signal(pkgStatusList)
904+ #return pkgStatusList
905+
906+ # get all source item in /etc/apt/sources.list
907+ def get_sources(self):
908+ source = aptsources.sourceslist.SourcesList()
909+ return source.list
910+
911+ # add ubuntukylin source in /etc/apt/sources.list
912+ def add_source_ubuntukylin(self):
913+ source = aptsources.sourceslist.SourcesList()
914+ for item in source.list:
915+ if(item.str().find("deb http://archive.ubuntukylin.com/ubuntukylin") != -1):
916+ return
917+
918+ source.add("deb", "http://archive.ubuntukylin.com/ubuntukylin/", "raring main", "")
919+ source.save()
920+
921+ # remove ubuntukylin source in /etc/apt/sources.list
922+ def remove_source_ubuntukylin(self):
923+ source = aptsources.sourceslist.SourcesList()
924+ sources = source.list
925+ for item in sources:
926+ if(item.str().find("deb http://archive.ubuntukylin.com/ubuntukylin") != -1):
927+ source.remove(item)
928+ source.save()
929+
930+if __name__ == "__main__":
931+ ad = AptDaemon(None)
932+
933+# print ad.check_pkgs_status(["gedit", "cairo-dock", "unity"])
934+# print ad.check_pkgs_status_rtn_list(["gedit", "cairo-dock", "unity", "haha", "hehe"])
935+# ad.apt_get_update()
936+ ad.add_source_ubuntukylin()
937+# ad.remove_source_ubuntukylin()
938+
939+ while True:
940+ print "\ninput your command: "
941+ cmd = raw_input()
942+ if cmd == "l":
943+ for name in ad.pkgNameList:
944+ print name + "\n"
945+ elif cmd == "i":
946+ print "input pkgName to install: "
947+ pkgName = raw_input()
948+ ad.install_pkg(pkgName)
949+ elif cmd == "n":
950+ print "input pkgName to uninstall: "
951+ pkgName = raw_input()
952+ ad.uninstall_pkg(pkgName)
953+ elif cmd == "u":
954+ print "input pkgName to update: "
955+ pkgName = raw_input()
956+ ad.update_pkg(pkgName)
957+ elif cmd == "c":
958+ print "input pkgName to check status: "
959+ pkgName = raw_input()
960+ print ad.check_pkg_status(pkgName)
961+ else:
962+ print "nothing..."
963+
964+# print ad.get_pkg_by_name('gedit')
965+ # pnl = ad.getpkglist()
966+ # print len(pnl)
967+# name1 = ad.search_pkgs_name('wesnoth-1.10-core')
968+# print name1
969+ # print 'aaa' + str(1)
970+# ad.install_pkg(name1)
971+# ad.uninstall_pkg(name1)
972+ # p = ad.get_pkg_by_name(name1)
973+ # print p.id
974+ # c = AptCache()
975+ # c.hahaha()
976+ # print c.hahaha()
977+ # pkgs = []
978+ # ca = apt.Cache()
979+ # i = 0
980+ # for a in ca:
981+ # i += 1
982+ # pkgs.append(a.name)
983+ # print a.name
984+ # print i
985+ # nanop = ca['nano']
986+ # print nanop
987+ # nanop.mark_install()
988+ # cache.commit()
989
990=== added file 'backend/aptdaemon/dbus_service/apt_dbus_service.py'
991--- backend/aptdaemon/dbus_service/apt_dbus_service.py 1970-01-01 00:00:00 +0000
992+++ backend/aptdaemon/dbus_service/apt_dbus_service.py 2014-03-08 03:45:16 +0000
993@@ -0,0 +1,215 @@
994+#!/usr/bin/python
995+# -*- coding: utf-8 -*-
996+
997+### BEGIN LICENSE
998+
999+# Copyright (C) 2013 National University of Defense Technology(NUDT) & Kylin Ltd
1000+
1001+# Author:
1002+# kobe Lee <xiangli@ubuntukylin.com>
1003+# maclin <majun@ubuntukylin.com>
1004+# Maintainer:
1005+# maclin <majun@ubuntukylin.com>
1006+
1007+# This program is free software: you can redistribute it and/or modify it
1008+# under the terms of the GNU General Public License version 3, as published
1009+# by the Free Software Foundation.
1010+#
1011+# This program is distributed in the hope that it will be useful, but
1012+# WITHOUT ANY WARRANTY; without even the implied warranties of
1013+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1014+# PURPOSE. See the GNU General Public License for more details.
1015+#
1016+# You should have received a copy of the GNU General Public License along
1017+# with this program. If not, see <http://www.gnu.org/licenses/>.
1018+
1019+### END LICENSE
1020+
1021+import sys
1022+import os
1023+import signal
1024+import glob
1025+import fcntl
1026+import shutil
1027+import logging
1028+import tempfile
1029+import subprocess
1030+import re
1031+import dbus
1032+import dbus.service
1033+import dbus.mainloop.glib
1034+from gi.repository import GObject
1035+import apt
1036+import aptsources.sourceslist
1037+import apt_pkg
1038+from server import PolicyKitService
1039+
1040+import time
1041+
1042+from apt_daemon import AptDaemon
1043+
1044+
1045+log = logging.getLogger('Daemon')
1046+
1047+
1048+INTERFACE = 'com.ubuntukylin.softwarecenter'
1049+UKPATH = '/'
1050+
1051+HTTP_SOURCE_UBUNTUKYLIN = "deb http://archive.ubuntukylin.com/ubuntukylin"
1052+DEB_SOURCE_UBUNTUKYLIN = "deb " + HTTP_SOURCE_UBUNTUKYLIN
1053+UBUNTUKYLIN_SOFTWARECENTER_ACTION = 'com.ubuntukylin.softwarecenter.action'
1054+
1055+class SoftwarecenterDbusService(dbus.service.Object):
1056+
1057+ def __init__ (self, bus, mainloop):
1058+
1059+ self.daemonApt = AptDaemon(self)
1060+ self.bus = bus
1061+ self.bus_name = dbus.service.BusName(INTERFACE, bus=bus)
1062+ print "SoftwarecenterDbusService:",self.bus_name
1063+ dbus.service.Object.__init__(self, self.bus_name, UKPATH)
1064+ self.mainloop = mainloop
1065+
1066+ def auth_with_policykit(self, sender, action):
1067+ if not sender:
1068+ raise ValueError('sender == None')
1069+
1070+ print "auth_with_policykit:", sender
1071+
1072+ obj = dbus.SystemBus().get_object('org.freedesktop.PolicyKit1',
1073+ '/org/freedesktop/PolicyKit1/Authority')
1074+ policykit = dbus.Interface(obj, 'org.freedesktop.PolicyKit1.Authority')
1075+
1076+ subject = ('system-bus-name', {'name': sender})
1077+ flags = dbus.UInt32(1) # AllowUserInteraction flag
1078+ details = { '' : '' }
1079+ cancel_id = '' # No cancellation id
1080+ (granted, notused, details) = policykit.CheckAuthorization(
1081+ subject, action, details, flags, cancel_id)
1082+ return granted
1083+
1084+ @dbus.service.method(INTERFACE, in_signature='', out_signature='')
1085+ def exit(self):
1086+ self.mainloop.quit()
1087+
1088+ # check ubuntukylin source is in /etc/apt/sources.list or not
1089+ @dbus.service.method(INTERFACE, in_signature='', out_signature='b', sender_keyword='sender')
1090+ def check_source_ubuntukylin(self, sender=None):
1091+
1092+ print "check_source_ubuntukylin..."
1093+
1094+ granted = self.auth_with_policykit(sender,UBUNTUKYLIN_SOFTWARECENTER_ACTION)
1095+ if not granted:
1096+ return False
1097+ source = aptsources.sourceslist.SourcesList()
1098+ for item in source.list:
1099+ if(item.str().find(DEB_SOURCE_UBUNTUKYLIN) != -1):
1100+ return True
1101+ return False
1102+
1103+ # add ubuntukylin source in /etc/apt/sources.list
1104+ @dbus.service.method(INTERFACE, in_signature='s', out_signature='')
1105+ def add_source_ubuntukylin(self, version):
1106+ source = aptsources.sourceslist.SourcesList(())
1107+ #????the check option should include version
1108+ if(self.check_source_ubuntukylin() is True):
1109+ return True
1110+ osversion = str(version) + (" main")
1111+ source.add("deb", HTTP_SOURCE_UBUNTUKYLIN, osversion, "")
1112+ source.save()
1113+ return True
1114+
1115+ # -------------------------software-center-------------------------
1116+ # install package sa:software_fetch_signal() and software_apt_signal()
1117+ @dbus.service.method(INTERFACE, in_signature='s', out_signature='')
1118+ def install(self, pkgName):
1119+ self.daemonApt.install_pkg(pkgName)
1120+ print "good"
1121+
1122+ # uninstall package sa:software_apt_signal()
1123+ @dbus.service.method(INTERFACE, in_signature='s', out_signature='')
1124+ def remove(self, pkgName):
1125+ self.daemonApt.uninstall_pkg(pkgName)
1126+
1127+ # update package sa:software_fetch_signal() and software_apt_signal()
1128+ @dbus.service.method(INTERFACE, in_signature='s', out_signature='')
1129+ def upgrade(self, pkgName):
1130+ self.daemonApt.upgrade_pkg(pkgName)
1131+
1132+
1133+
1134+ #????????????????????????????
1135+
1136+ # check packages status by pkgNameList sa:software_check_status_signal()
1137+ @dbus.service.method(INTERFACE, in_signature='as', out_signature='')
1138+ def check_pkgs_status(self, pkgNameList):
1139+ self.daemonApt.check_pkgs_status_rtn_list(pkgNameList)
1140+
1141+ # check one package status by pkgName
1142+ @dbus.service.method(INTERFACE, in_signature='s', out_signature='s')
1143+ def check_pkg_status(self, pkgName):
1144+ return self.daemonApt.check_pkg_status(pkgName)
1145+
1146+ # apt-get update sa:software_fetch_signal()
1147+ @dbus.service.method(INTERFACE, in_signature='', out_signature='')
1148+ def apt_get_update(self):
1149+ self.daemonApt.apt_get_update()
1150+
1151+ # package download status signal
1152+ '''parm mean
1153+ type:
1154+ start:start download
1155+ stop:all work is finish
1156+ done:all items download finished
1157+ fail:download failed
1158+ fetch:one item download finished
1159+ pulse:download status, this msg given a string like dict
1160+ msg:
1161+ a message of type, sometimes is None
1162+ '''
1163+ @dbus.service.signal(INTERFACE, signature='ss')
1164+ def software_fetch_signal(self, type, msg):
1165+ pass
1166+
1167+ # package install/update/remove signal
1168+ '''parm mean
1169+ type:
1170+ start:start work
1171+ stop:work finish
1172+ error:got a error
1173+ pulse:work status, this msg given a string like dict
1174+ msg:
1175+ a message of type, sometimes is None
1176+ '''
1177+ @dbus.service.signal(INTERFACE, signature='ss')
1178+ def software_apt_signal(self, type, msg):
1179+ pass
1180+
1181+ # get packages status signal
1182+ '''parm mean
1183+ dict{packageName, packageStatus}
1184+ packageStatus:
1185+ i:installed
1186+ u:installed and can update
1187+ n:notinstall
1188+ '''
1189+ @dbus.service.signal(INTERFACE, signature='as')
1190+ def software_check_status_signal(self, statusList):
1191+ pass
1192+
1193+ @dbus.service.signal(INTERFACE, signature='s')
1194+ def software_signal_test(self, msg):
1195+ pass
1196+
1197+if __name__ == '__main__':
1198+ os.environ["TERM"] = "xterm"
1199+ os.environ["PATH"] = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin"
1200+ os.environ["DEBIAN_FRONTEND"] = "noninteractive"
1201+ if os.path.exists("/var/lib/apt/lists/lock"):
1202+ os.remove("/var/lib/apt/lists/lock")
1203+ dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
1204+ GObject.threads_init()
1205+ mainloop = GObject.MainLoop()
1206+ signal.signal(signal.SIGINT, lambda : mainloop.quit())
1207+ Daemon(dbus.SystemBus(), mainloop)
1208+ mainloop.run()
1209
1210=== added file 'backend/aptdaemon/dbus_service/start_systemdbus.py'
1211--- backend/aptdaemon/dbus_service/start_systemdbus.py 1970-01-01 00:00:00 +0000
1212+++ backend/aptdaemon/dbus_service/start_systemdbus.py 2014-03-08 03:45:16 +0000
1213@@ -0,0 +1,47 @@
1214+#!/usr/bin/python
1215+# -*- coding: utf-8 -*-
1216+
1217+### BEGIN LICENSE
1218+
1219+# Copyright (C) 2013 National University of Defense Technology(NUDT) & Kylin Ltd
1220+
1221+# Author:
1222+# kobe Lee <xiangli@ubuntukylin.com>
1223+# maclin <majun@ubuntukylin.com>
1224+# Maintainer:
1225+# maclin <majun@ubuntukylin.com>
1226+
1227+# This program is free software: you can redistribute it and/or modify it
1228+# under the terms of the GNU General Public License version 3, as published
1229+# by the Free Software Foundation.
1230+#
1231+# This program is distributed in the hope that it will be useful, but
1232+# WITHOUT ANY WARRANTY; without even the implied warranties of
1233+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1234+# PURPOSE. See the GNU General Public License for more details.
1235+#
1236+# You should have received a copy of the GNU General Public License along
1237+# with this program. If not, see <http://www.gnu.org/licenses/>.
1238+
1239+### END LICENSE
1240+
1241+import os
1242+import signal
1243+import dbus
1244+import dbus.mainloop.glib
1245+from gi.repository import GObject
1246+from apt_dbus_service import SoftwarecenterDbusService
1247+
1248+if __name__ == '__main__':
1249+ os.environ["TERM"] = "xterm"
1250+ os.environ["PATH"] = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin"
1251+ os.environ["DEBIAN_FRONTEND"] = "noninteractive"
1252+ if os.path.exists("/var/lib/apt/lists/lock"):
1253+ os.remove("/var/lib/apt/lists/lock")
1254+
1255+ dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
1256+ GObject.threads_init()
1257+ mainloop = GObject.MainLoop()
1258+ signal.signal(signal.SIGINT, lambda : mainloop.quit())
1259+ SoftwarecenterDbusService(dbus.SystemBus(), mainloop)
1260+ mainloop.run()
1261
1262=== added file 'backend/aptdaemon/install.sh'
1263--- backend/aptdaemon/install.sh 1970-01-01 00:00:00 +0000
1264+++ backend/aptdaemon/install.sh 2014-03-08 03:45:16 +0000
1265@@ -0,0 +1,35 @@
1266+#!/bin/sh
1267+backendPath="/usr/lib/python2.7/dist-packages/ubuntukylin-softwarecenter-daemon"
1268+cd `dirname $0`
1269+cp ./data/youkersystem /usr/bin/
1270+echo "Copy systemdbus script to /usr/bin/"
1271+
1272+cp ./data/youkersession /usr/bin/
1273+echo "Copy sessiondbus script to /usr/bin/"
1274+
1275+
1276+cp ./conf/com.ubuntukylin.softwarecenter.service /usr/share/dbus-1/system-services/
1277+echo "Copy .service file to /usr/share/dbus-1/system-services/"
1278+
1279+cp ./conf/com.ubuntukylin.softwarecenter.policy /usr/share/polkit-1/actions/
1280+echo "Copy .policy file to /usr/share/polkit-1/actions/"
1281+
1282+cp ./conf/com.ubuntukylin.softwarecenter.conf /etc/dbus-1/system.d/
1283+echo "Copy .conf file to /etc/dbus-1/system.d/"
1284+
1285+if [ ! -d "$backendPath" ]; then
1286+ cp -rf ./dbus_service/ /usr/lib/python2.7/dist-packages/ubuntukylin-softwarecenter-daemon/
1287+ echo "Copy backend folder to /usr/lib/python2.7/dist-packages/ubuntukylin-softwarecenter-daemon/"
1288+else
1289+ rm -rf "$bakendPath"
1290+ cp -rf ./src /usr/lib/python2.7/dist-packages/ubuntukylin-softwarecenter-daemon/
1291+ echo "Copy backend folder to /usr/lib/python2.7/dist-packages/ubuntukylin-softwarecenter-daemon/"
1292+fi
1293+
1294+rm -f /usr/bin/ubuntukylin-softwarecenter-daemon.py
1295+echo "Remove /usr/bin/ubuntukylin-softwarecenter-daemon.py"
1296+
1297+chmod +x "$backendPath"/start_systemdbus.py
1298+ln -s "$backendPath"/start_systemdbus.py /usr/bin/ubuntukylin-softwarecenter-daemon.py
1299+echo "Build symbol link for service file"
1300+echo "^^ Now, You can run the ubuntukylin software center!"
1301
1302=== added directory 'backend/aptdaemon/keyrings'
1303=== added file 'backend/aptdaemon/keyrings/ubuntukylin-archive-keyring.gpg'
1304Binary files backend/aptdaemon/keyrings/ubuntukylin-archive-keyring.gpg 1970-01-01 00:00:00 +0000 and backend/aptdaemon/keyrings/ubuntukylin-archive-keyring.gpg 2014-03-08 03:45:16 +0000 differ
1305=== removed file 'backend/backend_apt.py'
1306--- backend/backend_apt.py 2014-02-28 07:51:15 +0000
1307+++ backend/backend_apt.py 1970-01-01 00:00:00 +0000
1308@@ -1,216 +0,0 @@
1309-#!/usr/bin/python
1310-# -*- coding: utf-8 -*-
1311-__author__ = 'Shine Huang'
1312-
1313-import apt
1314-import locale
1315-import data
1316-import apt.progress.base as apb
1317-from model.software import Software
1318-from data import softwareList
1319-
1320-from PyQt4.QtCore import *
1321-from PyQt4.QtGui import *
1322-try:
1323- _fromUtf8 = QString.fromUtf8
1324-except AttributeError:
1325- def _fromUtf8(s):
1326- return s
1327-
1328-
1329-class BackendApt(QObject):
1330- #the apt cache
1331- ca = ''
1332-
1333- def __init__(self):
1334- QObject.__init__(self)
1335- locale.setlocale(locale.LC_ALL, "zh_CN.UTF-8")
1336- print locale.getlocale()
1337- self.ca = apt.Cache()
1338-
1339- # get all packages
1340- def get_all_packages(self):
1341- sl = []
1342- self.ca.open()
1343- for pkg in self.ca:
1344- software = Software()
1345- software.package = pkg
1346- sl.append(software)
1347- # return sl
1348- self.emit(SIGNAL("getallpackagesover"), sl)
1349-
1350- # def get_all_packages(self):
1351- # self.ca.open()
1352- # for pkg in self.ca:
1353- # software = Software()
1354- # software.package = pkg
1355- # softwareList.append(software)
1356- # return softwareList
1357-
1358- # get package by pkgName
1359- def get_package_by_name(self, pkgName):
1360- for software in softwareList:
1361- if(software.name == pkgName):
1362- return software
1363- else:
1364- return None
1365-
1366- # update_package_status
1367- def update_package_status(self, pkgName):
1368- self.ca.open()
1369- for pkg in self.ca:
1370- if(pkg.name == pkgName):
1371- return pkg
1372- else:
1373- return None
1374-
1375- # install package
1376- def install_package(self, itemWidget):
1377- data.workMutex.acquire()
1378- data.isWorking = True
1379- data.workMutex.release()
1380- self.ca.open()
1381- itemWidget.software.package.mark_install()
1382-
1383- try:
1384- fp = FetchProcess()
1385- ap = AptProcess(itemWidget)
1386- self.connect(ap, SIGNAL("bmsg"), self.slot_emit_backend_msg)
1387- self.ca.commit(fp, ap)
1388- except Exception, e:
1389- print e
1390- print "install err"
1391-
1392- # update package
1393- def update_package(self, itemWidget):
1394- data.workMutex.acquire()
1395- data.isWorking = True
1396- data.workMutex.release()
1397- self.ca.open()
1398- itemWidget.software.package.mark_upgrade()
1399-
1400- try:
1401- fp = FetchProcess()
1402- ap = AptProcess(itemWidget)
1403- self.connect(ap, SIGNAL("bmsg"), self.slot_emit_backend_msg)
1404- self.ca.commit(fp, ap)
1405- except Exception, e:
1406- print e
1407- print "update err"
1408-
1409- # uninstall package
1410- def remove_package(self, itemWidget):
1411- data.workMutex.acquire()
1412- data.isWorking = True
1413- data.workMutex.release()
1414- self.ca.open()
1415- itemWidget.software.package.mark_delete()
1416-
1417- try:
1418- ap = AptProcess(itemWidget)
1419- self.connect(ap, SIGNAL("bmsg"), self.slot_emit_backend_msg)
1420- self.ca.commit(None, ap)
1421- except Exception, e:
1422- print e
1423- print "uninstall err"
1424-
1425- # add work to pool
1426- def add_work(self, itemWidget):
1427- data.workMutex.acquire()
1428- data.workPool.append(itemWidget)
1429- data.workMutex.release()
1430-
1431- def slot_emit_backend_msg(self, msg):
1432- self.emit(SIGNAL("backendmsg"), msg)
1433-
1434-
1435-class FetchProcess(apb.AcquireProgress):
1436- '''Fetch Process'''
1437- def __init__(self):
1438- apb.AcquireProgress.__init__(self)
1439-
1440- def done(self, item):
1441- print 'in FetchProcess done'
1442-
1443- def fail(self, item):
1444- print 'download failed'
1445-
1446- def fetch(self, item):
1447- print 'in FetchProcess fetch'
1448- # data.taskWidget.setText("download package")
1449-
1450- def ims_hit(self, item):
1451- print 'ims_hit'
1452-
1453- def media_change(self, media, drive):
1454- print 'media_change'
1455-
1456- def pulse(self, owner):
1457- thestr = "downloading : "+str(self.current_bytes)+" "+str(self.fetched_bytes)
1458- # print 'pulse ',thestr
1459- # data.taskWidget.setText(_fromUtf8(thestr))
1460-
1461- def start(self):
1462- # Reset all values.
1463- self.current_bytes = 0.0
1464- self.current_cps = 0.0
1465- self.current_items = 0
1466- self.elapsed_time = 0
1467- self.fetched_bytes = 0.0
1468- self.last_bytes = 0.0
1469- self.total_bytes = 0.0
1470- self.total_items = 0
1471- print 'fetch progress start ...'
1472- # data.taskWidget.setText("start download packages")
1473-
1474- def stop(self):
1475- print 'fetch progress stop ...'
1476- # data.taskWidget.setText("download finish")
1477-
1478-
1479-class AptProcess(apb.InstallProgress, QObject):
1480- '''Apt progress'''
1481- itemWidget = ''
1482- def __init__(self,itemWidget):
1483- apb.InstallProgress.__init__(self)
1484- QObject.__init__(self)
1485- # QObject.__init__()
1486- self.itemWidget = itemWidget
1487-
1488- def conffile(self, current, new):
1489- print 'there is a conffile question'
1490-
1491- def error(self, pkg, errormsg):
1492- print 'apt process error'
1493-
1494- def start_update(self):
1495- print 'apt process start work'
1496- self.emit(SIGNAL("bmsg"), "start apt process")
1497- # data.taskWidget.setText("start apt process")
1498-
1499- def finish_update(self):
1500- # finish point
1501- data.workMutex.acquire()
1502- data.isWorking = False
1503- data.workMutex.release()
1504-
1505- newPackage = data.backend.update_package_status(self.itemWidget.software.name)
1506- self.itemWidget.work_finished(newPackage)
1507- print 'apt process finished'
1508- self.emit(SIGNAL("bmsg"),"one work finish")
1509- # data.taskWidget.setText("one work finish")
1510-
1511- def status_change(self, pkg, percent, status):
1512- thestr = "percent : "+str(int(percent))+"% , status : "+status
1513- # print thestr
1514- self.emit(SIGNAL("bmsg"),thestr)
1515- # data.taskWidget.setText(_fromUtf8(thestr))
1516-
1517-def main():
1518- a = BackendApt()
1519- a.get_all_packages()
1520- a.install_package(a.get_package_by_name("abe").package)
1521-
1522-
1523-if __name__ == '__main__':
1524- main()
1525\ No newline at end of file
1526
1527=== removed file 'backend/backend_worker.py'
1528--- backend/backend_worker.py 2014-02-27 08:08:12 +0000
1529+++ backend/backend_worker.py 1970-01-01 00:00:00 +0000
1530@@ -1,36 +0,0 @@
1531-#!/usr/bin/python
1532-# -*- coding: utf-8 -*-
1533-__author__ = 'Shine Huang'
1534-import threading
1535-import data
1536-import time
1537-from ibackend import get_backend
1538-
1539-
1540-class BackendWorker(threading.Thread):
1541-
1542- # def __init__(self):
1543- # super(BackendWorker, self).__init__(self)
1544-
1545- def run(self):
1546- while(True):
1547- if(data.isWorking == False):
1548- data.workMutex.acquire()
1549- length = len(data.workPool)
1550- data.workMutex.release()
1551- if(length > 0):
1552- data.workMutex.acquire()
1553- itemWidget = data.workPool.pop(0)
1554- data.workMutex.release()
1555- print itemWidget.software.mark
1556- if(itemWidget.software.mark == data.WORK_TYPE_INSTALL):
1557- data.backend.install_package(itemWidget)
1558- elif(itemWidget.software.mark == data.WORK_TYPE_UPDATE):
1559- data.backend.update_package(itemWidget)
1560- elif(itemWidget.software.mark == data.WORK_TYPE_REMOVE):
1561- data.backend.remove_package(itemWidget)
1562- else:
1563- pass
1564- itemWidget.software.mark = ''
1565-
1566- time.sleep(0.5)
1567\ No newline at end of file
1568
1569=== removed file 'backend/ibackend.py'
1570--- backend/ibackend.py 2014-02-27 08:08:12 +0000
1571+++ backend/ibackend.py 1970-01-01 00:00:00 +0000
1572@@ -1,13 +0,0 @@
1573-#!/usr/bin/python
1574-# -*- coding: utf-8 -*-
1575-__author__ = 'Shine Huang'
1576-import data
1577-from backend_apt import BackendApt
1578-
1579-
1580-def get_backend():
1581- if (data.backend_type == 'apt'):
1582- return BackendApt()
1583- if (data.backend_type == 'packagekit'):
1584- #self.backend = BackendPackagekit()
1585- return None
1586\ No newline at end of file
1587
1588=== added file 'backend/installbackend.py'
1589--- backend/installbackend.py 1970-01-01 00:00:00 +0000
1590+++ backend/installbackend.py 2014-03-08 03:45:16 +0000
1591@@ -0,0 +1,149 @@
1592+#!/usr/bin/python
1593+# -*- coding: utf-8 -*
1594+
1595+### BEGIN LICENSE
1596+
1597+# Copyright (C) 2013 National University of Defense Technology(NUDT) & Kylin Ltd
1598+
1599+# Author:
1600+# maclin <majun@ubuntukylin.com>
1601+# Maintainer:
1602+# maclin <majun@ubuntukylin.com>
1603+
1604+# This program is free software: you can redistribute it and/or modify it
1605+# under the terms of the GNU General Public License version 3, as published
1606+# by the Free Software Foundation.
1607+#
1608+# This program is distributed in the hope that it will be useful, but
1609+# WITHOUT ANY WARRANTY; without even the implied warranties of
1610+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1611+# PURPOSE. See the GNU General Public License for more details.
1612+#
1613+# You should have received a copy of the GNU General Public License along
1614+# with this program. If not, see <http://www.gnu.org/licenses/>.
1615+
1616+### END LICENSE
1617+
1618+
1619+
1620+import dbus
1621+import os
1622+
1623+import locale
1624+
1625+from PyQt4.QtCore import *
1626+from PyQt4 import QtDBus
1627+
1628+from models.enums import (UBUNTUKYLIN_SERVICE_PATH,
1629+ UBUNTUKYLIN_INTERFACE_PATH,
1630+ AppActions,
1631+ PkgStates,
1632+ TransactionTypes)
1633+
1634+class DbusSignals:
1635+ APT_INSTALL_PROCESS = "software_apt_signal"
1636+
1637+
1638+class InstallBackend(QObject):
1639+
1640+ def __init__(self):
1641+ QObject.__init__(self)
1642+ locale.setlocale(locale.LC_ALL, "zh_CN.UTF-8")
1643+ print locale.getlocale()
1644+
1645+ self.iface = None
1646+
1647+ def _init_dbus_ifaces(self):
1648+
1649+ try:
1650+ bus = dbus.SystemBus()
1651+ except:
1652+ print ("could not initiate dbus")
1653+ return False
1654+
1655+ try:
1656+ obj = bus.get_object(UBUNTUKYLIN_SERVICE_PATH,
1657+ '/',
1658+ UBUNTUKYLIN_INTERFACE_PATH)
1659+ self.iface = dbus.Interface(obj, UBUNTUKYLIN_INTERFACE_PATH)
1660+ print "2222"
1661+
1662+ self.call_dbus_iface("check_source_ubuntukylin")
1663+
1664+ self.iface.connect_to_signal("software_fetch_signal",self._on_software_fetch_signal)
1665+ self.iface.connect_to_signal("software_apt_signal",self._on_software_apt_signal)
1666+ except dbus.DBusException:
1667+# bus_name = dbus.service.BusName('com.ubuntukylin.softwarecenter', bus)
1668+# self.dbusControler = SoftwarecenterDbusController(self, bus_name)
1669+ print "error"
1670+
1671+ #call the dbus functions by function name
1672+ def call_dbus_iface(self, funcname, kwargs=None):
1673+ if self.iface is None:
1674+ return None
1675+
1676+ func = getattr(self.iface,funcname)
1677+ if func is None:
1678+ return None
1679+
1680+ res = None
1681+ try:
1682+ res = func(kwargs)
1683+ except dbus.DBusException:
1684+ return None
1685+
1686+ return res
1687+
1688+ def _on_software_fetch_signal(self,type, msg):
1689+ print "_on_software_apt_signal"
1690+ print type
1691+ print msg
1692+
1693+ def _on_software_apt_signal(self,type, msg):
1694+ print "_on_software_apt_signal"
1695+ print type
1696+ print msg
1697+
1698+ def install_package(self,pkgname):
1699+ self.call_dbus_iface(AppActions.INSTALL,pkgname)
1700+
1701+ def remove_package(self,pkgname):
1702+ self.call_dbus_iface(AppActions.REMOVE,pkgname)
1703+
1704+ def upgrade_package(self,pkgname):
1705+ self.call_dbus_iface(AppActions.UPGRADE,pkgname)
1706+
1707+from PyQt4.QtGui import *
1708+import sys
1709+from dbus.mainloop.glib import DBusGMainLoop
1710+mainloop = DBusGMainLoop(set_as_default=True)
1711+
1712+def main():
1713+ app = QApplication(sys.argv)
1714+
1715+ w = QWidget()
1716+ w.setWindowTitle("测试")
1717+ w.setMaximumSize(320,240)
1718+ w.setMinimumSize(320,240)
1719+ w.resize(320,240)
1720+
1721+
1722+ instBackend = InstallBackend()
1723+ instBackend._init_dbus_ifaces()
1724+ instBackend.call_dbus_iface(AppActions.INSTALL,"gimp")
1725+# instBackend.call_dbus_iface(AppActions.INSTALL,"bareftp")
1726+# instBackend.call_dbus_iface(UK_DBUS_METHOD.INSTALL,"gimp")
1727+# instBackend.call_dbus_iface(UK_DBUS_METHOD.INSTALL,"gimp")
1728+
1729+ w.show()
1730+
1731+ sys.exit(app.exec_())
1732+
1733+
1734+
1735+if __name__ == "__main__":
1736+
1737+
1738+ main()
1739+
1740+ print "aaaa"
1741
1742=== added directory 'backend/piston'
1743=== added file 'backend/piston/__init__.py'
1744=== added file 'backend/piston/rnrclient_pristine.py'
1745--- backend/piston/rnrclient_pristine.py 1970-01-01 00:00:00 +0000
1746+++ backend/piston/rnrclient_pristine.py 2014-03-08 03:45:16 +0000
1747@@ -0,0 +1,195 @@
1748+"""This module provides the RatingsAndReviewsAPI class for talking to the
1749+ratings and reviews API, plus a few helper classes.
1750+"""
1751+
1752+from urllib import quote_plus
1753+from piston_mini_client import (
1754+ PistonAPI,
1755+ PistonResponseObject,
1756+ PistonSerializable,
1757+ returns,
1758+ returns_json,
1759+ returns_list_of,
1760+ )
1761+from piston_mini_client.validators import validate_pattern, validate
1762+#import pdb
1763+
1764+# These are factored out as constants for if you need to work against a
1765+# server that doesn't support both schemes (like http-only dev servers)
1766+PUBLIC_API_SCHEME = 'http'
1767+AUTHENTICATED_API_SCHEME = 'https'
1768+
1769+
1770+class ReviewRequest(PistonSerializable):
1771+ """A review request.
1772+
1773+ Instantiate one of these objects to describe a new review you wish to
1774+ submit, then pass it in as an argument to submit_review().
1775+ """
1776+ _atts = ('app_name', 'package_name', 'summary', 'version', 'review_text',
1777+ 'rating', 'language', 'origin', 'distroseries', 'arch_tag')
1778+ app_name = ''
1779+
1780+
1781+class ReviewsStats(PistonResponseObject):
1782+ """A ratings summary for a package/app.
1783+
1784+ This class will be automatically populated with JSON retrieved from the
1785+ server. Each ReviewStats object will have the following fields:
1786+ * package_name
1787+ * app_name
1788+ * ratings_total
1789+ * ratings_average
1790+ """
1791+ pass
1792+
1793+
1794+class ReviewDetails(PistonResponseObject):
1795+ """A detailed review description.
1796+
1797+ This class will be automatically populated with JSON retrieved from the
1798+ server. Each ReviewDetails object will have the following fields:
1799+ * id
1800+ * package_name
1801+ * app_name
1802+ * language
1803+ * date_created
1804+ * rating
1805+ * reviewer_username
1806+ * summary
1807+ * review_text
1808+ * hide
1809+ * version
1810+ """
1811+ pass
1812+
1813+
1814+class RatingsAndReviewsAPI(PistonAPI):
1815+ """A client for talking to the reviews and ratings API.
1816+
1817+ If you pass no arguments into the constructor it will try to connect to
1818+ localhost:8000 so you probably want to at least pass in the
1819+ ``service_root`` constructor argument.
1820+ """
1821+ default_service_root = 'http://localhost:8000/reviews/api/1.0'
1822+ default_content_type = 'application/x-www-form-urlencoded'
1823+
1824+ @returns_json
1825+ def server_status(self):
1826+ """Check the state of the server, to see if everything's ok."""
1827+ return self._get('server-status/', scheme=PUBLIC_API_SCHEME)
1828+
1829+ @validate_pattern('origin', r'[0-9a-z+-.:/]+', required=False)
1830+ @validate_pattern('distroseries', r'\w+', required=False)
1831+ @validate('days', int, required=False)
1832+ @returns_list_of(ReviewsStats)
1833+ def review_stats(self, origin='any', distroseries='any', days=None,
1834+ valid_days=(1, 3, 7)):
1835+ """Fetch ratings for a particular distroseries"""
1836+ url = 'review-stats/{0}/{1}/'.format(origin, distroseries)
1837+ if days is not None:
1838+ # the server only knows valid_days (1,3,7) currently
1839+ for valid_day in valid_days:
1840+ # pick the day from valid_days that is the next bigger than
1841+ # days
1842+ if days <= valid_day:
1843+ url += 'updates-last-{0}-days/'.format(valid_day)
1844+ break
1845+ return self._get(url, scheme=PUBLIC_API_SCHEME)
1846+
1847+ @validate_pattern('language', r'\w+', required=False)
1848+ @validate_pattern('origin', r'[0-9a-z+-.:/]+', required=False)
1849+ @validate_pattern('distroseries', r'\w+', required=False)
1850+ @validate_pattern('version', r'[-\w+.:~]+', required=False)
1851+ @validate_pattern('packagename', r'[a-z0-9.+-]+')
1852+ @validate('appname', str, required=False)
1853+ @validate('page', int, required=False)
1854+ @validate('sort', str, required=False)
1855+ @returns_list_of(ReviewDetails)
1856+ def get_reviews(self, packagename, language='any', origin='any',
1857+ distroseries='any', version='any', appname='', page=1, sort='helpful'):
1858+ """Fetch ratings and reviews for a particular package name.
1859+
1860+ If any of the optional arguments are provided, fetch reviews for that
1861+ particular app, language, origin, distroseries or version.
1862+ """
1863+ # pdb.set_trace()
1864+ if appname:
1865+ appname = quote_plus(';' + appname)
1866+ return self._get('reviews/filter/%s/%s/%s/%s/%s%s/page/%s/%s/' % (
1867+ language, origin, distroseries, version, packagename,
1868+ appname, page, sort),
1869+ scheme=PUBLIC_API_SCHEME)
1870+
1871+ @validate('review_id', int)
1872+ @returns(ReviewDetails)
1873+ def get_review(self, review_id):
1874+ """Fetch a particular review via its id."""
1875+ return self._get('reviews/%s/' % review_id)
1876+
1877+ @validate('review', ReviewRequest)
1878+ @returns(ReviewDetails)
1879+ def submit_review(self, review):
1880+ """Submit a rating/review."""
1881+ return self._post('reviews/', data=review,
1882+ scheme=AUTHENTICATED_API_SCHEME, content_type='application/json')
1883+
1884+ @validate('review_id', int)
1885+ @validate_pattern('reason', r'[^\n]+')
1886+ @validate_pattern('text', r'[^\n]+')
1887+ @returns_json
1888+ def flag_review(self, review_id, reason, text):
1889+ """Flag a review as being inappropriate"""
1890+ data = {'reason': reason,
1891+ 'text': text,
1892+ }
1893+ return self._post('reviews/%s/flags/' % review_id, data=data,
1894+ scheme=AUTHENTICATED_API_SCHEME)
1895+
1896+ @validate('review_id', int)
1897+ @validate_pattern('useful', 'True|False')
1898+ @returns_json
1899+ def submit_usefulness(self, review_id, useful):
1900+ """Submit a usefulness vote."""
1901+ return self._post('/reviews/%s/recommendations/' % review_id,
1902+ data={'useful': useful}, scheme=AUTHENTICATED_API_SCHEME)
1903+
1904+ @validate('review_id', int, required=False)
1905+ @validate_pattern('username', r'[^\n]+', required=False)
1906+ @returns_json
1907+ def get_usefulness(self, review_id=None, username=None):
1908+ """Get a list of usefulness filtered by username/review_id"""
1909+ if not username and not review_id:
1910+ return None
1911+
1912+ data = {}
1913+
1914+ if username:
1915+ data['username'] = username
1916+ if review_id:
1917+ data['review_id'] = str(review_id)
1918+
1919+ return self._get('usefulness/', args=data,
1920+ scheme=PUBLIC_API_SCHEME)
1921+
1922+ @validate('review_id', int)
1923+ @returns_json
1924+ def delete_review(self, review_id):
1925+ """Delete a review"""
1926+ return self._post('/reviews/delete/%s/' % review_id, data={},
1927+ scheme=AUTHENTICATED_API_SCHEME)
1928+
1929+ @validate('review_id', int)
1930+ @validate('rating', int)
1931+ @validate_pattern('summary', r'[^\n]+')
1932+ @validate('review_text', str)
1933+ @returns(ReviewDetails)
1934+ def modify_review(self, review_id, rating, summary, review_text):
1935+ """Modify an existing review"""
1936+ data = {
1937+ 'rating': rating,
1938+ 'summary': summary,
1939+ 'review_text': review_text
1940+ }
1941+ return self._put('/reviews/modify/%s/' % review_id, data=data,
1942+ scheme=AUTHENTICATED_API_SCHEME)
1943
1944=== added file 'backend/reviewratingspawn.py'
1945--- backend/reviewratingspawn.py 1970-01-01 00:00:00 +0000
1946+++ backend/reviewratingspawn.py 2014-03-08 03:45:16 +0000
1947@@ -0,0 +1,483 @@
1948+#!/usr/bin/python
1949+# -*- coding: utf-8 -*
1950+
1951+### BEGIN LICENSE
1952+
1953+# Copyright (C) 2013 National University of Defense Technology(NUDT) & Kylin Ltd
1954+
1955+# Author:
1956+# maclin <majun@ubuntukylin.com>
1957+# robert <luolei@ubuntukylin.com>
1958+# Maintainer:
1959+# maclin <majun@ubuntukylin.com>
1960+
1961+# This program is free software: you can redistribute it and/or modify it
1962+# under the terms of the GNU General Public License version 3, as published
1963+# by the Free Software Foundation.
1964+#
1965+# This program is distributed in the hope that it will be useful, but
1966+# WITHOUT ANY WARRANTY; without even the implied warranties of
1967+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1968+# PURPOSE. See the GNU General Public License for more details.
1969+#
1970+# You should have received a copy of the GNU General Public License along
1971+# with this program. If not, see <http://www.gnu.org/licenses/>.
1972+
1973+### END LICENSE
1974+
1975+
1976+
1977+import sys
1978+import os
1979+import pdb
1980+import time
1981+
1982+from string import join
1983+
1984+
1985+from piston_mini_client import APIError
1986+import httplib2
1987+import pickle
1988+
1989+import urllib2
1990+import json
1991+
1992+from backend.ubuntu_sw import SCREENSHOT_JSON_URL
1993+from models.enums import UBUNTUKYLIN_SOFTWARECENTER_CACHE_DIR
1994+
1995+from ubuntu_sw import SortMethods, ReviewSortMethods, Review
1996+from ubuntu_sw import (REVIEWS_SERVER, REVIEWS_URL)
1997+
1998+from piston.rnrclient_pristine import RatingsAndReviewsAPI
1999+RatingsAndReviewsAPI.default_service_root = REVIEWS_SERVER
2000+#"http://reviews.ubuntu.com/reviews/api/1.0"
2001+
2002+LARGE_VALUE = 10000000
2003+LEAST_RATE_TIMES = 8 # the least number a package should have been rated to get into the ranking list
2004+# sort methods by rating score
2005+class RatingSortMethods:
2006+ (INTEGRATE,
2007+ SCORE_FIRST,
2008+ FREQ_FIRST,
2009+ ) = range(3)
2010+
2011+
2012+from gi.repository import GObject
2013+import multiprocessing
2014+
2015+#a class to describe the total rating and review info
2016+class ReviewRatingStat(object):
2017+ def __init__(self,pkgname):
2018+ self.pkgname = pkgname
2019+ self.ratings_total = 0
2020+ self.ratings_average = 0
2021+ self.reviews_total = 0
2022+ self.useful = 0
2023+
2024+
2025+#多进程类,参数包括:指定要执行的方法和对应的参数,!!!!目前参数简单处理,后面再统一封装
2026+#其中方法从RatingsAndReviwsMethod中获取
2027+class SpawnProcess(GObject.GObject,multiprocessing.Process):
2028+ __gsignals__ = {
2029+ "spawn-data-available": (GObject.SIGNAL_RUN_LAST,
2030+ GObject.TYPE_NONE,
2031+ (GObject.TYPE_PYOBJECT,),
2032+ ),
2033+ "spawn-exited": (GObject.SIGNAL_RUN_LAST,
2034+ GObject.TYPE_NONE,
2035+ (int,),
2036+ ),
2037+ "spawn-error": (GObject.SIGNAL_RUN_LAST,
2038+ GObject.TYPE_NONE,
2039+ (str,),
2040+ ),
2041+ }
2042+
2043+ def __init__(self, func, kwargs=None):
2044+ super(SpawnProcess, self).__init__()
2045+ multiprocessing.Process.__init__(self)
2046+ self.func = func
2047+ self.kwargs = kwargs
2048+ print "\nEnter __init__ of SpawnThread...kwargs:\n", kwargs
2049+
2050+ def run(self):
2051+ print "\nEnter run of SpawnThread..."
2052+
2053+ if self.func is None:
2054+ print "\nEnter run...\n"
2055+ self.emit("spawn-error","####error parameters of calling function run")
2056+ return
2057+
2058+ func_method = getattr(RatingsAndReviwsMethod,self.func)
2059+ if func_method is None:
2060+ print "\nEnter run...\n"
2061+ self.emit("spawn-error","####error parameters of calling function run")
2062+ return
2063+
2064+ #run the function sync
2065+ if self.kwargs is None:
2066+ res = func_method()
2067+ else:
2068+ res = func_method(self.kwargs)
2069+ if not res:
2070+ self.emit("spawn-error","####error result from function run")
2071+ else:
2072+ self.emit("spawn-data-available",res)
2073+
2074+
2075+#执行方法封装类
2076+#所有的方法封装成静态方法,!!!!目前参数简单处理,后面再统一封装
2077+class RatingsAndReviwsMethod:
2078+
2079+ #return a list of Review
2080+ @staticmethod
2081+# def get_reviews(self, str_pkgname='gimp', callback=None, page=1):
2082+ def get_reviews(kwargs):
2083+ cachedir = None
2084+ #cachedir = os.path.join(UBUNTUKYLIN_SOFTWARECENTER_CACHE_DIR, "rnrclient")
2085+ #cachedir = "/home/maclin/test"
2086+ print cachedir
2087+ rnrclient = RatingsAndReviewsAPI() #????cache
2088+
2089+ piston_reviews = []
2090+ try:
2091+ piston_reviews = rnrclient.get_reviews(**kwargs)
2092+ # piston_reviews = rnrclient.get_reviews(packagename="gimp",language='zh_CN')
2093+ except ValueError as e:
2094+ print("failed to parse '%s'" % e)
2095+ #bug lp:709408 - don't print 404 errors as traceback when api request
2096+ # returns 404 error
2097+ except APIError as e:
2098+ print("_get_reviews_threaded: no reviews able to be retrieved for package: %s (%s, origin: %s)" % (options.pkgname, options.distroseries, options.origin))
2099+ print("_get_reviews_threaded: no reviews able to be retrieved: %s" % e)
2100+ except httplib2.ServerNotFoundError:
2101+ # switch to offline mode and try again
2102+ rnrclient._offline_mode = True
2103+ piston_reviews = rnrclient.get_reviews(**kwargs)
2104+ except:
2105+ print("get_reviews*****")
2106+
2107+ if piston_reviews is None:
2108+ piston_reviews = []
2109+
2110+ return piston_reviews
2111+
2112+ #return a list of screenshot file path
2113+ @staticmethod
2114+ def get_screenshots(kwargs):
2115+ screenshots = []
2116+
2117+ print "enter get_screenshots.....", kwargs
2118+
2119+ pkgname = kwargs['packagename']
2120+ version = kwargs['version']
2121+ cachedir = kwargs['cachedir']
2122+ print "pkgname:", pkgname
2123+ print "version:", version
2124+ print "cachdir:", cachedir
2125+
2126+ #get urls of screenshots
2127+ screenshotURL = SCREENSHOT_JSON_URL % pkgname
2128+
2129+ print screenshotURL
2130+ try:
2131+ urlFile = urllib2.urlopen(screenshotURL)
2132+ rawContent = urlFile.read()
2133+ print "good"
2134+ if not rawContent:
2135+ return []
2136+ except urllib2.HTTPError,e:
2137+ print e.code
2138+ except urllib2.URLError,e:
2139+ print str(e)
2140+
2141+ try:
2142+ jsonContent = json.loads(rawContent)
2143+ except ValueError as e:
2144+ print("can not decode: '%s' (%s)" % (content, e))
2145+ jsonContent = None
2146+ return []
2147+
2148+ if isinstance(jsonContent, dict):
2149+ # a list of screenshots as listsed online
2150+ screenshots = jsonContent['screenshots']
2151+ else:
2152+ # fallback to a list of screenshots as supplied by the axi
2153+ screenshots = []
2154+
2155+ print screenshots
2156+
2157+ #we should choose the suitable ones for showing
2158+ #????
2159+
2160+ screenshot_path_list = []
2161+
2162+ try:
2163+ for item in screenshots:
2164+ filename = item['small_image_url'].split(pkgname + '/')[1]
2165+ destfile = cachedir + pkgname + item['version'] + "_" + filename
2166+
2167+ urlFile = urllib2.urlopen(item['small_image_url'])
2168+ rawContent = urlFile.read()
2169+ if not rawContent:
2170+ continue
2171+
2172+ localFile = open(destfile,"wb")
2173+ localFile.write(rawContent)
2174+ localFile.close()
2175+ screenshot_path_list.append(destfile)
2176+
2177+ except urllib2.HTTPError,e:
2178+ print e.code
2179+ except urllib2.URLError,e:
2180+ print str(e)
2181+
2182+ print "####Revice screenshots:\n", screenshot_path_list
2183+
2184+ return screenshot_path_list
2185+
2186+ #return a list of ReviewRatingStat
2187+ @staticmethod
2188+ def get_review_rating_stats():
2189+ print "enter get_review_rating_stats...."
2190+
2191+ rnrArray = {}
2192+ try:
2193+ rnr = RatingsAndReviewsAPI()
2194+ statlist = rnr.review_stats()
2195+
2196+ index = 0
2197+ for stat in statlist:
2198+ rnrStat = ReviewRatingStat(stat.package_name)
2199+ rnrStat.ratings_average = float(stat.ratings_average)
2200+ rnrStat.ratings_total = int(stat.ratings_total)
2201+ rnrStat.pkgname = stat.package_name
2202+ rnrArray[stat.package_name] = rnrStat
2203+
2204+ print "stat list count: ", len(rnrArray)
2205+
2206+ return rnrArray
2207+
2208+ except Exception as e:
2209+ print("Error in get_review_rating_stats...")
2210+ print(e.args)
2211+ return {}
2212+
2213+
2214+ @staticmethod
2215+ def get_toprated_stats(kwargs):
2216+ topcount = int(kwargs['topcount'])
2217+ sortingMethod = kwargs['sortingMethod']
2218+
2219+ print "get_toprated_stats: ", topcount, sortingMethod
2220+ resList = {}
2221+
2222+ try:
2223+ rnr = RatingsAndReviewsAPI()
2224+ print(rnr.server_status())
2225+ ratingList = rnr.review_stats()
2226+ for pac in ratingList:
2227+ pac.ratings_average = float(pac.ratings_average)
2228+ pac.ratings_total = int(pac.ratings_total)
2229+
2230+ ratingAvg = range(len(ratingList))
2231+ ratingTotal = range(len(ratingList))
2232+ for i in range(len(ratingList)):
2233+ ratingAvg[i] = ratingList[i].ratings_average
2234+ ratingTotal[i] = ratingList[i].ratings_total
2235+ # see http://blog.csdn.net/pi9nc/article/details/10762877 for the IMDB.COM ranking method
2236+ ratingWR = range(len(ratingList)) # weighted rating score for each package
2237+ ratedPac = 0 # number of packages have been rated by more than one user
2238+ scoreSum = 0 # sum score of all rating
2239+ rateTimesTotal = 0 # rating times in total
2240+ for i in range(len(ratingList)):
2241+ if ratingList[i].ratings_total > 0:
2242+ ratedPac += 1
2243+ scoreSum += ratingList[i].ratings_total * ratingList[i].ratings_average
2244+ rateTimesTotal += ratingList[i].ratings_total
2245+ avgScoreAll = scoreSum/rateTimesTotal
2246+ leastRateTimes = LEAST_RATE_TIMES
2247+ for i in range(len(ratingList)):
2248+ ratingWR[i] = (leastRateTimes*avgScoreAll +
2249+ ratingList[i].ratings_total*ratingList[i].ratings_average) / \
2250+ (leastRateTimes + ratingList[i].ratings_total)
2251+ # print(_("We got the rating list "))
2252+ # print(_("Average score of all package is %s, number of scored package is %d") %
2253+ # (avgScoreAll, ratedPac))
2254+ index = sorted(range(len(ratingWR)), key=lambda x: ratingWR[x], reverse=True)
2255+ ratingList = [ratingList[i] for i in index]
2256+ ratingWR = [ratingWR[i] for i in index]
2257+
2258+
2259+ if sortingMethod is None or sortingMethod == RatingSortMethods.INTEGRATE:
2260+ resList = ratingList
2261+ if sortingMethod == RatingSortMethods.FREQ_FIRST:
2262+ cmp_rating = lambda x, y: \
2263+ cmp(x.ratings_total * LARGE_VALUE + x.ratings_average,
2264+ y.ratings_total * LARGE_VALUE + y.ratings_average)
2265+
2266+ resList = sorted(ratingList,
2267+ cmp_rating,
2268+ reverse=True)
2269+ if sortingMethod == RatingSortMethods.SCORE_FIRST:
2270+ cmp_rating = lambda x, y: \
2271+ cmp(x.ratings_average * LARGE_VALUE + x.ratings_total,
2272+ y.ratings_average * LARGE_VALUE + y.ratings_total)
2273+ resList = sorted(ratingList,
2274+ cmp_rating,
2275+ reverse=True)
2276+
2277+ resList = resList[1:topcount]
2278+ rnrStatList = {}
2279+ for item in resList:
2280+ stat = ReviewRatingStat(item.package_name)
2281+ stat.ratings_total = item.ratings_total
2282+ stat.ratings_average = item.ratings_average
2283+ rnrStatList[item.package_name] = stat
2284+
2285+ return rnrStatList
2286+
2287+ except Exception as e:
2288+ print("Error in RatingList.get_rating_list(): ")
2289+ print(e.args)
2290+ return resList
2291+
2292+
2293+ @staticmethod
2294+ def get_reviews_list(self, str_pkgname='gimp', callback=None, page=1):
2295+
2296+ print "\nenter RatingsAndReviwsMethod, get_reviews.......\n"
2297+ import urllib
2298+
2299+ # force stdout to be utf-8
2300+ import codecs
2301+ sys.stdout = codecs.getwriter('utf8')(sys.stdout)
2302+
2303+ # dump all reviews
2304+ rnr = RatingsAndReviewsAPI(service_root="http://reviews.ubuntu.com/reviews/api/1.0")
2305+
2306+ sat_res = []
2307+ sat_res = rnr.server_status()
2308+ print sat_res
2309+
2310+ res = rnr.review_stats()
2311+
2312+ print len(res)
2313+
2314+ # dump all reviews
2315+ for stat in res:
2316+ print("stats for (pkg='%s', app: '%s'): avg=%s total=%s" % (
2317+ stat.package_name, stat.app_name, stat.ratings_average,
2318+ stat.ratings_total))
2319+ reviews = rnr.get_reviews(
2320+ language="zh_CN", origin="ubuntu", distroseries="precise",
2321+ packagename=stat.package_name,
2322+ appname=urllib.quote_plus(stat.app_name.encode("utf-8")))
2323+
2324+ for review in reviews:
2325+ print("rating: %s user=%s" % (review.rating,
2326+ review.reviewer_username))
2327+ print(review.summary)
2328+ print(review.review_text)
2329+ print("\n")
2330+
2331+ # get individual ones
2332+ reviews = rnr.get_reviews(language="zh_CN", origin="ubuntu",
2333+ distroseries="maverick", packagename="unace", appname="ACE")
2334+ print(reviews)
2335+ print(rnr.get_reviews(language="zh_CN", origin="ubuntu", distroseries="saucy",
2336+ packagename="aclock.app"))
2337+ print(rnr.get_reviews(language="zh_CN", origin="ubuntu", distroseries="saucy",
2338+ packagename="unace", appname="ACE"))
2339+
2340+
2341+class RatingsAndReviewsTest:
2342+
2343+ def __init__(self):
2344+
2345+ self.language = 'zh_CN'
2346+ self.origin = 'any'
2347+ self.sort_method = ReviewSortMethods.REVIEW_SORT_METHODS[0] #set default method
2348+ self.distroseries = 'any'
2349+
2350+ self._reviews = {}
2351+
2352+ def start_get_reviews(self, str_pkgname='gimp', callback=None, page=1):
2353+ """ public api, triggers fetching a review and calls callback
2354+ when its ready
2355+ """
2356+ #old parameters:translated_app, callback, page=1, language=None, sort=0, relaxed=False
2357+ language = self.language
2358+ origin = self.origin
2359+ distroseries = self.distroseries
2360+ sort_method = self.sort_method
2361+ version = "any"
2362+
2363+ """
2364+ kwargs = {"language": language,
2365+ "origin": origin,
2366+ "distroseries": distroseries,
2367+ "packagename": str_pkgname,#options.pkgname.split(':')[0], #multiarch..
2368+ "version": version,
2369+ "page": page, #int(options.page),
2370+ "sort" : sort_method,
2371+ }
2372+ """
2373+ kwargs = {"language": language,
2374+ "packagename": "gimp", #multiarch..
2375+ "distroseries": "saucy",
2376+ }
2377+
2378+ spawn_helper = SpawnProcess("get_reviews",kwargs)
2379+ spawn_helper.connect("data-available", self._on_reviews_ready, str_pkgname, callback)
2380+ spawn_helper.start()
2381+
2382+ def _on_reviews_ready(self, spawn_helper, piston_reviews, str_pkgname,
2383+ callback):
2384+ # convert into our review objects
2385+ print "\nEnter rnrclient_uk.py, on_reviews_helper_data"
2386+ reviews = []
2387+ for r in piston_reviews:
2388+ reviews.append(Review.from_piston_mini_client(r))
2389+ # add to our dicts and run callback
2390+ self._reviews[str_pkgname] = reviews
2391+ if callback:
2392+ callback(str_pkgname, self._reviews[str_pkgname])
2393+ return False
2394+
2395+
2396+def _reviews_ready_callback(str_pkgname, reviews_data, my_votes=None,
2397+ action=None, single_review=None):
2398+ print "\n***Enter _reviews_ready_callback..."
2399+ print str_pkgname
2400+ for review in reviews_data:
2401+ print("rating: %s user=%s" % (review.rating,
2402+ review.reviewer_username))
2403+ print(review.summary)
2404+ print(review.review_text)
2405+ print("\n")
2406+ print "\n\n"
2407+
2408+
2409+if __name__ == "__main__":
2410+
2411+ req = urllib2.Request("http://screenshots.ubuntu.com/screenshots/g/gimp/10064_small1.png")
2412+ urlFile = urllib2.urlopen(req)
2413+ print urlFile.info()
2414+
2415+
2416+# test = RatingsAndReviewsTest()
2417+# piston_reviews = test.start_get_reviews('gimp',_reviews_ready_callback)
2418+
2419+# piston_reviews = test.get_reviews('gimp',_reviews_ready_callback)
2420+# print piston_reviews
2421+ while True:
2422+ print "********"
2423+ time.sleep(1)
2424+
2425+
2426+
2427+
2428+
2429+
2430+
2431
2432=== removed file 'backend/server.py'
2433--- backend/server.py 2014-02-27 08:08:12 +0000
2434+++ backend/server.py 1970-01-01 00:00:00 +0000
2435@@ -1,53 +0,0 @@
2436-#!/usr/bin/python
2437-# -*- coding: utf-8 -*-
2438-
2439-import dbus.service
2440-
2441-class AccessDeniedException(dbus.DBusException):
2442- '''This exception is raised when some operation is not permitted.'''
2443-
2444- _dbus_error_name = 'com.ubuntukylin.softwarecenter.AccessDeniedException'
2445-
2446-
2447-class PolicyKitService():
2448- '''A D-BUS service that uses PolicyKit for authorization.'''
2449-
2450- def _check_permission(self, sender, action):
2451- if not sender: raise ValueError('sender == None')
2452- kit = dbus.SystemBus().get_object('org.freedesktop.PolicyKit1', '/org/freedesktop/PolicyKit1/Authority')
2453- kit = dbus.Interface(kit, 'org.freedesktop.PolicyKit1.Authority')
2454- (granted, _, details) = kit.CheckAuthorization(
2455- ('system-bus-name', {'name': sender}),
2456- action, {}, dbus.UInt32(1), '', timeout=600)
2457- return granted
2458-
2459- #def _check_permission(self, sender, action):
2460- # '''
2461- # Verifies if the specified action is permitted, and raises
2462- # an AccessDeniedException if not.
2463- #
2464- # The caller should use ObtainAuthorization() to get permission.
2465- # '''
2466-
2467- # try:
2468- # if sender:
2469- # kit = dbus.SystemBus().get_object('org.freedesktop.PolicyKit1', '/org/freedesktop/PolicyKit1/Authority')
2470- # kit = dbus.Interface(kit, 'org.freedesktop.PolicyKit1.Authority')
2471- #
2472- # # Note that we don't use CheckAuthorization with bus name
2473- # # details because we have no ways to get the PID of the
2474- # # front-end, so we're left with checking that its bus name
2475- # # is authorised instead
2476- # # See http://bugzilla.gnome.org/show_bug.cgi?id=540912
2477- # (granted, _, details) = kit.CheckAuthorization(
2478- # ('system-bus-name', {'name': sender}),
2479- # action, {}, dbus.UInt32(1), '', timeout=600)
2480- #
2481- # if not granted:
2482- # raise AccessDeniedException('Session not authorized by PolicyKit')
2483-
2484- # except AccessDeniedException:
2485- # raise
2486-
2487- # except dbus.DBusException, ex:
2488- # raise AccessDeniedException(ex.message)
2489
2490=== removed file 'backend/sourcelist_apt.py'
2491--- backend/sourcelist_apt.py 2014-02-27 08:08:12 +0000
2492+++ backend/sourcelist_apt.py 1970-01-01 00:00:00 +0000
2493@@ -1,3 +0,0 @@
2494-#!/usr/bin/python
2495-# -*- coding: utf-8 -*-
2496-__author__ = ''
2497
2498=== added file 'backend/ubuntu_sw.py'
2499--- backend/ubuntu_sw.py 1970-01-01 00:00:00 +0000
2500+++ backend/ubuntu_sw.py 2014-03-08 03:45:16 +0000
2501@@ -0,0 +1,128 @@
2502+# Copyright (C) 2009 Canonical
2503+#
2504+# Authors:
2505+# Michael Vogt
2506+#
2507+# This program is free software; you can redistribute it and/or modify it under
2508+# the terms of the GNU General Public License as published by the Free Software
2509+# Foundation; version 3.
2510+#
2511+# This program is distributed in the hope that it will be useful, but WITHOUT
2512+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
2513+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
2514+# details.
2515+#
2516+# You should have received a copy of the GNU General Public License along with
2517+# this program; if not, write to the Free Software Foundation, Inc.,
2518+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2519+
2520+# These defines of variables and classes are imported from ubuntu software center
2521+
2522+from gettext import gettext as _
2523+
2524+# reviews
2525+ #REVIEWS_SERVER = (os.environ.get("SOFTWARE_CENTER_REVIEWS_HOST") or
2526+# "http://reviews.ubuntu.com/reviews/api/1.0")
2527+ #REVIEWS_URL = (REVIEWS_SERVER + "/reviews/filter/%(language)s/%(origin)s/"
2528+ # "%(distroseries)s/%(version)s/%(pkgname)s%(appname)s/")
2529+
2530+REVIEWS_SERVER = ("http://reviews.ubuntu.com/reviews/api/1.0")
2531+REVIEWS_URL = (REVIEWS_SERVER + "%(distroseries)s/%(version)s/%(pkgname)s%(appname)s/")
2532+
2533+
2534+#define the const screenshot_JSON_URL, copy from Ubuntu.py of ubuntu-sw
2535+SCREENSHOT_JSON_URL = "http://screenshots.ubuntu.com/json/package/%s"
2536+
2537+# screenshot handling
2538+SCREENSHOT_THUMB_URL = ("http://screenshots.ubuntu.com/"
2539+ "thumbnail-with-version/%(pkgname)s/%(version)s")
2540+SCREENSHOT_LARGE_URL = ("http://screenshots.ubuntu.com/"
2541+ "screenshot-with-version/%(pkgname)s/%(version)s")
2542+
2543+
2544+#=============================================================================begin
2545+#Added from softwarecenter.enums
2546+# sorting
2547+class SortMethods:
2548+ (UNSORTED,
2549+ BY_ALPHABET,
2550+ BY_SEARCH_RANKING,
2551+ BY_CATALOGED_TIME,
2552+ BY_TOP_RATED,
2553+ ) = range(5)
2554+
2555+
2556+class ReviewSortMethods:
2557+ REVIEW_SORT_METHODS = ['helpful', 'newest']
2558+ REVIEW_SORT_LIST_ENTRIES = [_('Most helpful first'), _('Newest first')]
2559+#=============================================================================end
2560+
2561+#=============================================================================begin
2562+#Added from softwarecenter.backend.reviews.__init__
2563+#Modified:
2564+# replace app with pkgname
2565+# remove classmethod from_json
2566+class Review(object):
2567+ """A individual review object """
2568+ def __init__(self, pkgname):
2569+ # a softwarecenter.db.database.Application object
2570+# self.app = app
2571+# self.app_name = app.appname
2572+ self.package_name = pkgname
2573+ # the review items that the object fills in
2574+ self.id = None
2575+ self.language = None
2576+ self.summary = ""
2577+ self.review_text = ""
2578+ self.package_version = None
2579+ self.date_created = None
2580+ self.rating = None
2581+ self.reviewer_username = None
2582+ self.reviewer_displayname = None
2583+ self.version = ""
2584+ self.usefulness_total = 0
2585+ self.usefulness_favorable = 0
2586+ # this will be set if tryint to submit usefulness for this review
2587+ # failed
2588+ self.usefulness_submit_error = False
2589+ self.delete_error = False
2590+ self.modify_error = False
2591+
2592+ def __repr__(self):
2593+ return "[Review id=%s review_text='%s' reviewer_username='%s']" % (
2594+ self.id, self.review_text, self.reviewer_username)
2595+
2596+ def __cmp__(self, other):
2597+ # first compare version, high version number first
2598+ vc = upstream_version_compare(self.version, other.version)
2599+ if vc != 0:
2600+ return vc
2601+ # then wilson score
2602+ uc = cmp(wilson_score(self.usefulness_favorable,
2603+ self.usefulness_total),
2604+ wilson_score(other.usefulness_favorable,
2605+ other.usefulness_total))
2606+ if uc != 0:
2607+ return uc
2608+ # last is date
2609+ t1 = datetime.datetime.strptime(self.date_created, '%Y-%m-%d %H:%M:%S')
2610+ t2 = datetime.datetime.strptime(other.date_created,
2611+ '%Y-%m-%d %H:%M:%S')
2612+ return cmp(t1, t2)
2613+
2614+ @classmethod
2615+ def from_piston_mini_client(cls, other):
2616+ """ converts the rnrclieent reviews we get into
2617+ "our" Review object (we need this as we have more
2618+ attributes then the rnrclient review object)
2619+ """
2620+ pkgname = other.package_name
2621+ review = cls(pkgname)
2622+ for (attr, value) in other.__dict__.items():
2623+ if not attr.startswith("_"):
2624+ setattr(review, attr, value)
2625+ return review
2626+
2627+#=============================================================================end
2628+
2629+
2630
2631=== modified file 'data/__init__.py'
2632--- data/__init__.py 2014-02-28 07:51:15 +0000
2633+++ data/__init__.py 2014-03-08 03:45:16 +0000
2634@@ -11,8 +11,7 @@
2635 # counts
2636 installedCount = -1
2637 upgradableCount = -1
2638-# how many softwares show in a setp
2639-showSoftwareStep = 20
2640+
2641 # package backend work pool
2642 workPool = []
2643 # True : when pool not empty, thread stop
2644@@ -27,10 +26,10 @@
2645 workMutex = threading.RLock()
2646
2647 # global backend & service
2648-from backend.ibackend import get_backend
2649-from service.software_bo import SoftwareBO
2650-backend = get_backend()
2651-sbo = SoftwareBO()
2652+#from backend.ibackend import get_backend
2653+#from service.software_bo import SoftwareBO
2654+#backend = get_backend()
2655+#sbo = SoftwareBO()
2656
2657 # task view
2658 taskWidget = ''
2659
2660=== added directory 'data/ads'
2661=== added file 'data/ads/ad1.png'
2662Binary files data/ads/ad1.png 1970-01-01 00:00:00 +0000 and data/ads/ad1.png 2014-03-08 03:45:16 +0000 differ
2663=== added file 'data/ads/ad2.png'
2664Binary files data/ads/ad2.png 1970-01-01 00:00:00 +0000 and data/ads/ad2.png 2014-03-08 03:45:16 +0000 differ
2665=== added file 'data/ads/ad3.png'
2666Binary files data/ads/ad3.png 1970-01-01 00:00:00 +0000 and data/ads/ad3.png 2014-03-08 03:45:16 +0000 differ
2667=== added file 'data/ads/adback.png'
2668Binary files data/ads/adback.png 1970-01-01 00:00:00 +0000 and data/ads/adback.png 2014-03-08 03:45:16 +0000 differ
2669=== added directory 'data/category'
2670=== added file 'data/category/devel'
2671--- data/category/devel 1970-01-01 00:00:00 +0000
2672+++ data/category/devel 2014-03-08 03:45:16 +0000
2673@@ -0,0 +1,139 @@
2674+anjuta
2675+basic256
2676+bless
2677+boa-constructor
2678+bouml
2679+bpython
2680+build-essential
2681+bzr
2682+cameleon
2683+cervisia
2684+clips
2685+codeblocks
2686+codelite
2687+conduit
2688+conglomerate
2689+cssed
2690+ddd
2691+devhelp
2692+diffuse
2693+dreampie
2694+drpython
2695+eclipse
2696+efte
2697+emacs-snapshot
2698+emacs23
2699+emma
2700+entagged
2701+eric
2702+fluid
2703+frama-c
2704+freeguide
2705+freeplane
2706+gambas2
2707+gamera-gui
2708+gaphor
2709+gazpacho
2710+geany
2711+ghex
2712+giggle
2713+gitg
2714+gmanedit
2715+gmysqlcc
2716+gnuserv
2717+gpaco
2718+gphpedit
2719+gsql
2720+gwrite
2721+hotwire
2722+idle
2723+idle-python2.6
2724+idle-python2.7
2725+idle-python3.1
2726+idle-python3.2
2727+idle3
2728+jedit
2729+jeex
2730+jhbuild
2731+jmeter
2732+juffed
2733+kabikaboo
2734+kapptemplate
2735+kate
2736+kcachegrind
2737+kdesvn
2738+kdevelop
2739+kiki
2740+kildclient
2741+kodos
2742+kompare
2743+kturtle
2744+kuiviewer
2745+kwrite
2746+lazarus
2747+leafpad
2748+lemon
2749+lyx
2750+medit
2751+mlview
2752+monkeystudio
2753+monodevelop
2754+monodoc-http
2755+mousepad
2756+mysql-client
2757+mysql-navigator
2758+mysql-server
2759+nedit
2760+netbeans
2761+okteta
2762+phoronix-test-suite
2763+pida
2764+podbrowser
2765+pype
2766+pypibrowser
2767+pyragua
2768+pyroom
2769+python-poker2d
2770+qa-assistant
2771+qdevelop
2772+qgit
2773+qsource-highlight
2774+qtcreator
2775+quanta
2776+rapidsvn
2777+rbbr
2778+regexxer
2779+reinteract
2780+relational
2781+salasaga
2782+scite
2783+sciteproj
2784+scribes
2785+sdlbasic
2786+shoes
2787+source-highlight-ide
2788+spe
2789+sqlitebrowser
2790+sqliteman
2791+subcommander
2792+svn-workbench
2793+sysprof
2794+tea
2795+texmacs
2796+texworks
2797+tkcvs
2798+tora
2799+umbrello
2800+usbprog
2801+vim
2802+virtaal
2803+visualvm
2804+vite
2805+winefish
2806+winpdb
2807+wxformbuilder
2808+xacobeo
2809+xdot
2810+xmlcopyeditor
2811+xsddiagram
2812+xvile
2813
2814=== added file 'data/category/game'
2815--- data/category/game 1970-01-01 00:00:00 +0000
2816+++ data/category/game 2014-03-08 03:45:16 +0000
2817@@ -0,0 +1,410 @@
2818+a7xpg
2819+abe
2820+abuse
2821+acm
2822+adanaxisgpl
2823+adonthell
2824+airstrike
2825+alex4
2826+alien-arena
2827+alienblaster
2828+amor
2829+amphetamine
2830+anagramarama
2831+angrydd
2832+antigravitaattori
2833+armagetronad
2834+asc
2835+asciijump
2836+assaultcube
2837+asylum
2838+atanks
2839+atomix
2840+atris
2841+attal
2842+balazar
2843+balazarbrothers
2844+balder2d
2845+ballz
2846+barrage
2847+bastet
2848+battleball
2849+beneath-a-steel-sky
2850+berusky
2851+billard-gl
2852+biloba
2853+biniax2
2854+black-box
2855+blobandconquer
2856+blobby
2857+bloboats
2858+blobwars
2859+blockattack
2860+blockout2
2861+blocks-of-the-undead
2862+bomber
2863+bomberclone
2864+boswars
2865+bouncy
2866+bovo
2867+briquolo
2868+brutalchess
2869+btanks
2870+bubbros
2871+bugsquish
2872+burgerspace
2873+bygfoot
2874+bzflag
2875+ceferino
2876+cgoban
2877+childsplay
2878+chromium-bsu
2879+circuslinux
2880+colorcode
2881+connectagram
2882+crack-attack
2883+crawl-tiles
2884+criticalmass
2885+csmash
2886+cultivation
2887+cytadela
2888+defendguin
2889+desmume
2890+dodgindiamond2
2891+dopewars
2892+dossizola
2893+dreamchess
2894+eboard
2895+egoboo
2896+einstein
2897+ember
2898+empcommand
2899+enemylines3
2900+enemylines7
2901+enigma
2902+epiphany
2903+etoys
2904+etw
2905+extremetuxracer
2906+exult
2907+fceu
2908+filler
2909+fillets-ng
2910+flight-of-the-amazon-queen
2911+flightgear
2912+flobopuyo
2913+fofix
2914+foobillard
2915+freealchemist
2916+freecol
2917+freedink
2918+freedink-dfarc
2919+freedm
2920+freedoom
2921+freedroid
2922+freedroidrpg
2923+freetennis
2924+freevial
2925+fretsonfire-game
2926+frogatto
2927+frozen-bubble
2928+funguloids
2929+funnyboat
2930+gamazons
2931+gamine
2932+gbrainy
2933+gcompris
2934+gemdropx
2935+gfceu
2936+gfpoken
2937+ghextris
2938+gl-117
2939+glchess
2940+glest
2941+glines
2942+glob2
2943+glpeces
2944+gltron
2945+gmameui
2946+gmchess
2947+gmult
2948+gnect
2949+gnibbles
2950+gnobots2
2951+gnome-breakout
2952+gnome-chess
2953+gnome-hearts
2954+gnome-mastermind
2955+gnome-sudoku
2956+gnomine
2957+gnotravex
2958+gnotski
2959+gnubg
2960+gnubik
2961+gnudoq
2962+gnujump
2963+golly
2964+goplay
2965+gplanarity
2966+granatier
2967+granule
2968+gravitation
2969+gravitywars
2970+grhino
2971+gsoko
2972+gtali
2973+gtans
2974+gtkballs
2975+gtkboard
2976+gunroar
2977+gvrng
2978+gweled
2979+hannah
2980+hedgewars
2981+hex-a-hop
2982+hexalate
2983+hitori
2984+holdingnuts
2985+holotz-castle
2986+iagno
2987+icebreaker
2988+ii-esu
2989+jigzo
2990+jumpnbump
2991+kajongg
2992+kanagram
2993+kanatest
2994+kapman
2995+katomic
2996+kball
2997+kbattleship
2998+kblackbox
2999+kblocks
3000+kbounce
3001+kbreakout
3002+kdiamond
3003+ketm
3004+kfourinline
3005+kgoldrunner
3006+khangman
3007+kigo
3008+kiki-the-nano-bot
3009+killbots
3010+kiriki
3011+kjumpingcube
3012+klickety
3013+klines
3014+kmahjongg
3015+kmines
3016+knetwalk
3017+knights
3018+kobodeluxe
3019+kolf
3020+kollision
3021+konquest
3022+koules
3023+kpat
3024+krank
3025+kreversi
3026+ksame
3027+kshisen
3028+ksirk
3029+kspaceduel
3030+ksquares
3031+ksudoku
3032+ktron
3033+ktuberling
3034+kubrick
3035+laby
3036+lbreakout2
3037+lgeneral
3038+lightsoff
3039+lightyears
3040+lincity
3041+lincity-ng
3042+linthesia
3043+liquidwar
3044+littlewizard
3045+lletters
3046+lmarbles
3047+lmemory
3048+londonlaw
3049+lordsawar
3050+love
3051+lskat
3052+ltris
3053+luola
3054+madbomber
3055+maelstrom
3056+mah-jong
3057+mathwar
3058+meritous
3059+micropolis
3060+mirrormagic
3061+mmpong-gl
3062+mokomaze
3063+monkey-bubble
3064+monster-masher
3065+monsterz
3066+moon-lander
3067+mousetrap
3068+mu-cade
3069+mupen64plus
3070+nethack-qt
3071+nethack-x11
3072+netpanzer
3073+neverball
3074+neverputt
3075+nexuiz
3076+nighthawk
3077+nikwi
3078+njam
3079+noiz2sa
3080+numptyphysics
3081+oneisenough
3082+oolite
3083+open-invaders
3084+openarena
3085+openbve
3086+opencity
3087+openttd
3088+openyahtzee
3089+orbital-eunuchs-sniper
3090+overgod
3091+pacman
3092+palapeli
3093+pangzero
3094+parsec47
3095+passage
3096+pathogen
3097+pathological
3098+peg-e
3099+pegsolitaire
3100+penguin-command
3101+pente
3102+performous
3103+pinball
3104+pingus
3105+pioneers
3106+pipewalker
3107+pixbros
3108+pixfrogger
3109+plee-the-bear
3110+pokerth
3111+pouetchess
3112+powder
3113+powermanga
3114+pq
3115+primrose
3116+projectfootball
3117+projectl
3118+pybridge
3119+pydance
3120+pynagram
3121+pyracerz
3122+pyscrabble
3123+pysycache
3124+qgo
3125+quadrapassel
3126+quarry
3127+raincat
3128+renpy
3129+renpy-demo
3130+renpy-thequestion
3131+ri-li
3132+robocode
3133+rott
3134+rrootage
3135+sandboxgamemaker
3136+sauerbraten
3137+scorched3d
3138+scummvm
3139+sdl-ball
3140+searchandrescue
3141+simutrans
3142+singularity
3143+slashem-gtk
3144+slashem-sdl
3145+slashem-x11
3146+slimevolley
3147+slingshot
3148+sm
3149+smc
3150+snake4
3151+solarwolf
3152+sopwith
3153+space-orbit
3154+spider
3155+spout
3156+spring
3157+springlobby
3158+stormbaancoureur
3159+stroq
3160+supertux
3161+supertuxkart
3162+swell-foop
3163+tagua
3164+tanglet
3165+tatan
3166+tecnoballz
3167+teeworlds
3168+teg
3169+tennix
3170+tetzle
3171+tictactoe-ng
3172+tipptrainer
3173+titanion
3174+tmw
3175+tomatoes
3176+toppler
3177+torcs
3178+torus-trooper
3179+torus-trooper-pure
3180+trackballs
3181+transcend
3182+tremulous
3183+trigger-rally
3184+tumiki-fighters
3185+tuxmath
3186+tuxpuck
3187+tuxtype
3188+tworld
3189+uqm
3190+val-and-rick
3191+vbaexpress
3192+vectoroids
3193+viruskiller
3194+visualboyadvance
3195+vodovod
3196+vor
3197+warmux
3198+warsow
3199+warzone2100
3200+wesnoth-1.8
3201+whichwayisup
3202+widelands
3203+xabacus
3204+xbill
3205+xboard
3206+xboing
3207+xconq
3208+xdemineur
3209+xgalaga
3210+xjump
3211+xmabacus
3212+xmahjongg
3213+xmille
3214+xmoto
3215+xoids
3216+xqf
3217+xsabre
3218+xscavenger
3219+xscorch
3220+xshogi
3221+xwelltris
3222+xword
3223+yabause-gtk
3224+yabause-qt
3225+yahtzeesharp
3226+zatacka
3227+zaz
3228
3229=== added file 'data/category/graphic'
3230--- data/category/graphic 1970-01-01 00:00:00 +0000
3231+++ data/category/graphic 2014-03-08 03:45:16 +0000
3232@@ -0,0 +1,86 @@
3233+aqsis
3234+boats
3235+darkroom
3236+dia
3237+digikam
3238+drgeo
3239+earth3d
3240+emerillon
3241+eog
3242+evolvotron
3243+f-spot
3244+feh
3245+flphoto
3246+fotowall
3247+fotoxx
3248+fracplanet
3249+fyre
3250+g3dviewer
3251+geeqie-gps
3252+gextractwinicons
3253+gimp
3254+gliv
3255+gnome-paint
3256+gosmore
3257+gpaint
3258+gpicview
3259+gpixpod
3260+gpppon
3261+gpscorrelate
3262+gpxviewer
3263+gthumb
3264+gtkam
3265+gwenview
3266+hugin
3267+inkscape
3268+javamorph
3269+josm
3270+kcolorchooser
3271+kcoloredit
3272+kgraphviewer
3273+kiconedit
3274+ktoon
3275+latexdraw
3276+lprof
3277+merkaartor
3278+meshlab
3279+mirage
3280+mm3d
3281+mtpaint
3282+mypaint
3283+nip2
3284+ocrfeeder
3285+openclipart
3286+pencil
3287+phatch
3288+pixelize
3289+pornview
3290+posterazor
3291+qliss3d
3292+qtpfsgui
3293+rawstudio
3294+rawtherapee
3295+rgbpaint
3296+ristretto
3297+scantailor
3298+scribus
3299+scribus-ng
3300+shotwell
3301+showfoto
3302+skencil
3303+slicer
3304+structure-synth
3305+sunflow
3306+tgif
3307+therion
3308+therion-viewer
3309+trimage
3310+tuxpaint
3311+ufraw
3312+winff
3313+wings3d
3314+xaos
3315+xaralx
3316+xfig
3317+xpaint
3318+xsane
3319
3320=== added file 'data/category/internet'
3321--- data/category/internet 1970-01-01 00:00:00 +0000
3322+++ data/category/internet 2014-03-08 03:45:16 +0000
3323@@ -0,0 +1,217 @@
3324+amsn
3325+amule
3326+arcjobtool
3327+avahi-discover
3328+axel-kapt
3329+ayttm
3330+azureus
3331+balsa
3332+bareftp
3333+bitstormlite
3334+bittornado
3335+blam
3336+blogilo
3337+blogtk
3338+bluefish
3339+bmon
3340+bookmarkbridge
3341+buxon
3342+cgmail
3343+choqok
3344+chromium-browser
3345+clamz
3346+claws-mail
3347+dc-qt
3348+deluge
3349+desktop-webmail
3350+dfo
3351+dooble
3352+driftnet
3353+dwww
3354+eiskaltdcpp
3355+ekiga
3356+elinks
3357+email-reminder
3358+emesene
3359+empathy
3360+enigmail
3361+etherape
3362+ettercap
3363+evolution
3364+fatrat
3365+fennec
3366+filezilla
3367+firefox
3368+firefox-launchpad-plugin
3369+flashplugin-installer
3370+flush
3371+foff
3372+fqterm
3373+freepops-updater-gnome
3374+freespeak
3375+ftp
3376+fwbuilder
3377+g2ipmsg
3378+gajim
3379+gallery-uploader
3380+gamt
3381+ganyremote
3382+gerstensaft
3383+gftp
3384+giftoxic
3385+giftui
3386+gigolo
3387+giver
3388+gmail-notify
3389+gnome-btdownload
3390+gnome-gmail
3391+gnome-gmail-notifier
3392+gnome-lirc-properties
3393+gnome-mud
3394+gnome-nettool
3395+gnome-ppp
3396+gns3
3397+gnubiff
3398+gnunet-gtk
3399+gnunet-qt
3400+gobby
3401+gobby-0.5
3402+gosa-desktop
3403+gpodder
3404+gq
3405+gresolver
3406+gtk-gnutella
3407+gtwitter
3408+gurlchecker
3409+gwakeonlan
3410+gwget
3411+gwibber
3412+gyrus
3413+icedtea-plugin
3414+ike
3415+instantbird
3416+iptux
3417+jd
3418+jftp
3419+kadu
3420+kcheckgmail
3421+kflickr
3422+kftpgrabber
3423+kget
3424+kgmailnotifier
3425+kimagemapeditor
3426+kita2
3427+kleopatra
3428+klinkstatus
3429+kmail
3430+kmess
3431+kmldonkey
3432+knode
3433+kompozer
3434+konversation
3435+kopete
3436+kphone
3437+kppp
3438+kradioripper
3439+krdc
3440+krfb
3441+ktorrent
3442+kvirc
3443+kvpnc
3444+last-exit
3445+lat
3446+lekhonee-gnome
3447+licq
3448+liferea
3449+links2
3450+linphone
3451+logjam
3452+lostirc
3453+lottanzb
3454+luakit
3455+mail-notification
3456+mango-lassi
3457+mediatomb
3458+midori
3459+miro
3460+mldonkey-gui
3461+multiget
3462+mumble
3463+murmur
3464+museeq
3465+musetup-gtk
3466+mythnettv
3467+netemul
3468+netsurf
3469+nicotine
3470+nmapsi4
3471+nzb
3472+openfetion
3473+openvas-client
3474+packeth
3475+pidgin
3476+pidgin-otr
3477+pidgin-plugin-pack
3478+ploader
3479+postr
3480+prismstumbler
3481+psi
3482+putty
3483+pyneighborhood
3484+qbittorrent
3485+qfreefax
3486+qnapi
3487+qterm
3488+quassel
3489+quicksynergy
3490+qutecom
3491+qutim
3492+qwit
3493+rekonq
3494+rutilt
3495+rygel
3496+sadms
3497+scenic
3498+seamonkey
3499+seamonkey-chatzilla
3500+seamonkey-mailnews
3501+secpanel
3502+slimrat
3503+spamassassin
3504+ssvnc
3505+subdownloader
3506+sylph-searcher
3507+sylpheed
3508+telegnome
3509+theorur
3510+thunderbird
3511+tkabber
3512+transgui
3513+transmission-gtk
3514+transmission-qt
3515+tsclient
3516+ttb
3517+tucan
3518+twinkle
3519+twitux
3520+umit
3521+unison-gtk
3522+upnp-inspector
3523+valknut
3524+vidalia
3525+vinagre
3526+w3af
3527+webhttrack
3528+webissues
3529+wicd
3530+wifi-radar
3531+willowng
3532+wireshark
3533+x11vnc
3534+xchat
3535+xchat-gnome
3536+xpn
3537+yarssr
3538+youtranslate
3539+zenmap
3540+zim
3541
3542=== added file 'data/category/multimedia'
3543--- data/category/multimedia 1970-01-01 00:00:00 +0000
3544+++ data/category/multimedia 2014-03-08 03:45:16 +0000
3545@@ -0,0 +1,249 @@
3546+aconnectgui
3547+aeolus
3548+alsamixergui
3549+alsoft-conf
3550+ams
3551+amsynth
3552+aqualung
3553+ardour
3554+ario
3555+asoundconf-gtk
3556+asunder
3557+audacity
3558+audex
3559+avidemux-qt
3560+bangarang
3561+banshee
3562+beast
3563+bitmeter
3564+bluemindo
3565+bombono-dvd
3566+brasero
3567+canorus
3568+cecilia
3569+clementine
3570+composite
3571+cowbell
3572+decibel-audio-player
3573+denemo
3574+devede
3575+djplay
3576+dragonplayer
3577+dvd95
3578+dvdrip
3579+dvdstyler
3580+earcandy
3581+easytag
3582+enna
3583+espeak-gui
3584+esperanza
3585+exaile
3586+exfalso
3587+extace
3588+fmit
3589+foo-yc20
3590+freebirth
3591+freecycle
3592+freemix
3593+freevo
3594+freewheeling
3595+freqtweak
3596+frescobaldi
3597+galan
3598+gamix
3599+gbemol
3600+gcdmaster
3601+genpo
3602+gespeaker
3603+gimmix
3604+gjacktransport
3605+glame
3606+glurp
3607+gmlive
3608+gmorgan
3609+gmpc
3610+gmtp
3611+gmusicbrowser
3612+gnome-alsamixer
3613+gnome-media-player
3614+gnome-mplayer
3615+gnomebaker
3616+gnomeradio
3617+gnusound
3618+goattracker
3619+gopchop
3620+griffith
3621+gtick
3622+gtk-recordmydesktop
3623+gtkguitune
3624+gtklick
3625+gtkpod
3626+guayadeque
3627+guitarix
3628+guvcview
3629+gwc
3630+gxmms2
3631+hexter
3632+hipo
3633+horgand
3634+hornsey
3635+hydrogen
3636+ifpgui
3637+imagination
3638+intone
3639+iriverter
3640+jack-keyboard
3641+jack-mixer
3642+jack-rack
3643+jackbeat
3644+jackeq
3645+jajuk
3646+jamin
3647+jkmeter
3648+jlgui
3649+jokosher
3650+jsymphonic
3651+juk
3652+k3b
3653+k9copy
3654+kaffeine
3655+kdenlive
3656+kid3
3657+kid3-qt
3658+kino
3659+kluppe
3660+kmetronome
3661+kmidimon
3662+kmix
3663+kmouth
3664+kmplayer
3665+kover
3666+kplayer
3667+kradio4
3668+kscd
3669+kwave
3670+lastfm
3671+liguidsoap
3672+lingot
3673+listen
3674+livemix
3675+lives
3676+ll-scope
3677+longomatch
3678+luciole
3679+lyricue
3680+me-tv
3681+meterbridge
3682+mhwaveedit
3683+milkytracker
3684+minirok
3685+minitube
3686+mistelix
3687+mixxx
3688+moovida
3689+mp3diags
3690+mp3splt-gtk
3691+mplinuxman
3692+mscore
3693+muine
3694+muse
3695+mx44
3696+mythtv
3697+ncmpcpp
3698+nekobee
3699+nted
3700+nvtv
3701+oggconvert
3702+ogmrip
3703+openmovieeditor
3704+openshot
3705+padevchooser
3706+paman
3707+paprefs
3708+patchage
3709+pavucontrol
3710+pavumeter
3711+phasex
3712+picard
3713+pitivi
3714+potamus
3715+projectm-jack
3716+projectm-pulseaudio
3717+promoe
3718+puredata
3719+pygmy
3720+pykaraoke
3721+pympd
3722+qarecord
3723+qjackctl
3724+qmidinet
3725+qmidiroute
3726+qmmp
3727+qpxtool
3728+qsampler
3729+qsynth
3730+qtractor
3731+quark
3732+quodlibet
3733+radiotray
3734+rakarrack
3735+rezound
3736+rhythmbox
3737+ripoff
3738+ripperx
3739+rosegarden
3740+scolily
3741+seq24
3742+smplayer
3743+solfege
3744+sonata
3745+songwrite
3746+sooperlooper
3747+sound-juicer
3748+soundconverter
3749+soundkonverter
3750+specimen
3751+stopmotion
3752+streamtuner
3753+subtitlecomposer
3754+subtitleeditor
3755+swami
3756+sweep
3757+syncropated
3758+tagtool
3759+tangerine
3760+thelastripper
3761+themonospot
3762+thoggen
3763+timemachine
3764+timidity-interfaces-extra
3765+tinyeartrainer
3766+todiscgui
3767+toonloop
3768+totem
3769+totem-xine
3770+transcriber
3771+transmageddon
3772+traverso
3773+tunapie
3774+tuxguitar
3775+vagalume
3776+videocut
3777+videoporama
3778+viridian
3779+vkeybd
3780+vlc
3781+vmpk
3782+wavbreaker
3783+wavesurfer
3784+xawtv
3785+xcdroast
3786+xcfa
3787+xfburn
3788+xfmpc
3789+xjadeo
3790+xmms2tray
3791+yoshimi
3792+zapping
3793+zynaddsubfx
3794+zynjacku
3795
3796=== added file 'data/category/office'
3797--- data/category/office 1970-01-01 00:00:00 +0000
3798+++ data/category/office 2014-03-08 03:45:16 +0000
3799@@ -0,0 +1,77 @@
3800+almanah
3801+artha
3802+babiloo
3803+basket
3804+bibledit
3805+biblememorizer
3806+bibletime
3807+bibshelf
3808+calibre
3809+cbrpager
3810+chmsee
3811+comix
3812+djvusmooth
3813+ebview
3814+epdfview
3815+evince
3816+fantasdic
3817+fbreader
3818+gaiksaurus
3819+gaupol
3820+gbgoffice
3821+gedit
3822+gnome-office
3823+gnote
3824+gnumeric
3825+goldendict
3826+gpdftext
3827+gtodo
3828+gtranslator
3829+gv
3830+gwaei
3831+jpilot
3832+kasumi
3833+katoob
3834+kbedic
3835+kbibtex
3836+kchmviewer
3837+kexi
3838+kjots
3839+knotes
3840+kobby
3841+koffice
3842+kpresenter
3843+kspread
3844+kthesaurus
3845+kword
3846+libreoffice-calc
3847+libreoffice-draw
3848+libreoffice-impress
3849+libreoffice-math
3850+libreoffice-writer
3851+lokalize
3852+mupdf
3853+nfoview
3854+omaque
3855+omegat
3856+opendict
3857+pdfedit
3858+qcomicbook
3859+qdacco
3860+qrfcview
3861+qstardict
3862+qtodo
3863+referencer
3864+rhinote
3865+stardict
3866+tasks
3867+tomboy
3868+treb
3869+tuxcards
3870+txtreader
3871+xchm
3872+xournal
3873+xpad
3874+xpdf
3875+zanshin
3876+zhone
3877
3878=== added file 'data/category/other'
3879--- data/category/other 1970-01-01 00:00:00 +0000
3880+++ data/category/other 2014-03-08 03:45:16 +0000
3881@@ -0,0 +1,544 @@
3882+accerciser
3883+agave
3884+alarm-clock
3885+alarm-clock-applet
3886+alltray
3887+apertium-tolk
3888+aptoncd
3889+apturl
3890+aqemu
3891+arandr
3892+aranym
3893+ark
3894+arkose-gui
3895+auto-multiple-choice
3896+autokey-gtk
3897+autokey-qt
3898+avant-window-navigator
3899+awn-settings
3900+backintime-gnome
3901+baobab
3902+battery-stats
3903+bleachbit
3904+blueproximity
3905+bluetile
3906+bluewho
3907+boinc-manager
3908+btnx-config
3909+bug-buddy
3910+bum
3911+byobu
3912+cairo-clock
3913+cairo-dock
3914+cameramonitor
3915+camorama
3916+catfish
3917+cellwriter
3918+checkbox-gtk
3919+cheese
3920+clamtk
3921+clipit
3922+clusterssh
3923+colorname
3924+compiz
3925+computer-janitor-gtk
3926+configure-debian
3927+congruity
3928+contacts
3929+controlaula
3930+convertall
3931+cournol
3932+cryptkeeper
3933+cutecom
3934+daemonfs
3935+dasher
3936+dates
3937+deb-gview
3938+debgtd
3939+deja-dup
3940+deskscribe
3941+desktopnova
3942+desktopnova-tray
3943+diff-ext
3944+diffpdf
3945+disksearch
3946+dkopp
3947+dlume
3948+docbook2odf
3949+docky
3950+dolphin
3951+dosbox
3952+dosemu
3953+drapes
3954+driconf
3955+dvdisaster
3956+dvdrip-queue
3957+e-uae
3958+easycrypt
3959+easystroke
3960+efax-gtk
3961+eiciel
3962+emelfm2
3963+emu8051
3964+esteidutil
3965+evilvte
3966+fceux
3967+ferret
3968+fet
3969+file-roller
3970+filelight
3971+firestarter
3972+flamerobin
3973+flegita
3974+florence
3975+flpsed
3976+font-manager
3977+fontforge
3978+fontmatrix
3979+fontypython
3980+foomatic-gui
3981+foxtrotgps
3982+fpm2
3983+fprint-demo
3984+fraqtive
3985+freemind
3986+fslint
3987+furiusisomount
3988+fusion-icon
3989+fuss-launcher
3990+fvwm
3991+gadmin-bind
3992+gadmin-dhcpd
3993+gadmin-openvpn-client
3994+gadmin-openvpn-server
3995+gadmin-proftpd
3996+gadmin-rsync
3997+gadmin-samba
3998+gadmin-squid
3999+gally
4000+galternatives
4001+gameconqueror
4002+gapcmon
4003+gastman
4004+gbirthday
4005+gbonds
4006+gcalctool
4007+gcipher
4008+gco
4009+gcolor2
4010+gconf-cleaner
4011+gconf-editor
4012+gconjugue
4013+gcstar
4014+gcursor
4015+gddccontrol
4016+gdebi
4017+gdebi-kde
4018+gdecrypt
4019+gdesklets
4020+gdevilspie
4021+gdmap
4022+gebabbel
4023+geotranz
4024+gfaim
4025+gfax
4026+ghemical
4027+gip
4028+gisomount
4029+gjiten
4030+gjots2
4031+gkdebconf
4032+gkrellm
4033+glabels
4034+glogg
4035+glom
4036+gmobilemedia
4037+gnash
4038+gnoemoe
4039+gnome-activity-journal
4040+gnome-art
4041+gnome-blog
4042+gnome-color-chooser
4043+gnome-commander
4044+gnome-device-manager
4045+gnome-do
4046+gnome-format
4047+gnome-genius
4048+gnome-phone-manager
4049+gnome-photo-printer
4050+gnome-rdp
4051+gnome-schedule
4052+gnome-specimen
4053+gnome-splashscreen-manager
4054+gnome-subtitles
4055+gnome-system-monitor
4056+gnome-terminal
4057+gnome-translate
4058+gnome-utils
4059+gnomecatalog
4060+gnomekiss
4061+gnomint
4062+gnotime
4063+gnucash
4064+gnumed-client
4065+gok
4066+goobox
4067+googlizer
4068+gourmet
4069+gpa
4070+gpar2
4071+gparted
4072+gpass
4073+gpointing-device-settings
4074+gpomme
4075+gprename
4076+gpsdrive
4077+gpsprune
4078+gquilt
4079+grafx2
4080+gramps
4081+grandr
4082+grcm
4083+grdesktop
4084+greenwich
4085+gringotts
4086+groundcontrol
4087+grsync
4088+gscan2pdf
4089+gshutdown
4090+gsmartcontrol
4091+gstm
4092+gtablix
4093+gtg
4094+gtimelog
4095+gtk-chtheme
4096+gtk-redshift
4097+gtkatlantic
4098+gtkdiskfree
4099+gtkhash
4100+gtkorphan
4101+gtkperf
4102+gtkterm
4103+gtkvncviewer
4104+gtkwhiteboard
4105+guake
4106+gucharmap
4107+gufw
4108+gui-apt-key
4109+gwenrename
4110+gwhere
4111+gworldclock
4112+gxneur
4113+hamster-applet
4114+hannah-foo2zjs
4115+hardinfo
4116+hotssh
4117+hplip
4118+htop
4119+idjc
4120+im-config
4121+im-switch
4122+inkblot
4123+iok
4124+ircp-tray
4125+isag
4126+isomaster
4127+istanbul
4128+jargoninformatique
4129+jclic
4130+jobs-admin
4131+jumpapplet
4132+jxplorer
4133+kaddressbook
4134+kalarm
4135+kamoso
4136+kanyremote
4137+kbackup
4138+kcalc
4139+kcemu
4140+kcharselect
4141+kcollectd
4142+kdepasswd
4143+kdf
4144+kdiff3
4145+kdocker
4146+kdrill
4147+keepassx
4148+kepas
4149+keurocalc
4150+keyboardcast
4151+keysafe
4152+keytouch
4153+keytouch-editor
4154+kfax
4155+kfilereplace
4156+kfind
4157+kfloppy
4158+kfritz
4159+kgeography
4160+kgpg
4161+kgrab
4162+khmerconverter
4163+kinfocenter
4164+kiten
4165+klash
4166+klavaro
4167+klettres
4168+klipper
4169+kmag
4170+kmediafactory
4171+kmousetool
4172+kmymoney
4173+knemo
4174+konsole
4175+konsolekalendar
4176+kontact
4177+kontrolpack
4178+korganizer
4179+kpackagekit
4180+kphotoalbum
4181+kplato
4182+kraft
4183+krecipes
4184+krename
4185+krita
4186+kruler
4187+krusader
4188+kshutdown
4189+ksnapshot
4190+ksshaskpass
4191+ksysguard
4192+ksystemlog
4193+kteatime
4194+ktimer
4195+ktimetracker
4196+ktouch
4197+kupfer
4198+kuser
4199+kvkbd
4200+kvpm
4201+kwalletmanager
4202+kwordquiz
4203+kx11grab
4204+labyrinth
4205+language-selector
4206+lernid
4207+lifeograph
4208+lightspark
4209+likewise-open-gui
4210+live-magic
4211+lshw-gtk
4212+luckybackup
4213+lunch
4214+lxde
4215+lynis
4216+magicicada
4217+marble
4218+matchbox-keyboard
4219+mdbtools-gmdb
4220+meld
4221+memaker
4222+metacity
4223+mgm
4224+minbar
4225+mlterm
4226+mnemosyne
4227+moserial
4228+mtink
4229+multisync
4230+muon
4231+muon-installer
4232+mutter
4233+mythbuntu-control-centre
4234+nagstamon
4235+nautilus-cd-burner
4236+nautilus-scripts-manager
4237+navit
4238+nemiver
4239+netapplet
4240+netrek-client-cow
4241+notecase
4242+obconf
4243+obextool
4244+okular
4245+onboard
4246+openbox
4247+openerp-client
4248+openstv
4249+osmo
4250+othman
4251+packagesearch
4252+parcellite
4253+parley
4254+partitionmanager
4255+password-gorilla
4256+pauker
4257+pcmanfm
4258+pdfchain
4259+pdfmod
4260+pdfsam
4261+pdfshuffler
4262+penguintv
4263+pessulus
4264+pgadmin3
4265+pgdesigner
4266+pinot
4267+pithos
4268+planner
4269+playitslowly
4270+poedit
4271+pondus
4272+prefixsuffix
4273+prelude-notify
4274+pterm
4275+pureadmin
4276+purrr
4277+pybackpack
4278+pychess
4279+pyntor
4280+pypar2
4281+pyrenamer
4282+pysdm
4283+pytrainer
4284+qemu-launcher
4285+qemulator
4286+qlandkartegt
4287+qlix
4288+qprogram-starter
4289+qshutdown
4290+qtemu
4291+qtgain
4292+qtm
4293+qtnx
4294+qtstalker
4295+quitcount
4296+qviaggiatreno
4297+qwbfsmanager
4298+qwo
4299+rar
4300+recorditnow
4301+rednotebook
4302+remmina
4303+resapplet
4304+revelation
4305+rootstock
4306+roxterm
4307+rsibreak
4308+sabayon
4309+sagasu
4310+sakura
4311+sawfish
4312+screenie-qt
4313+screenruler
4314+seahorse
4315+searchmonkey
4316+semantik
4317+sentinella
4318+series60-remote
4319+shrinkta
4320+shutter
4321+simdock
4322+simple-ccsm
4323+simple-scan
4324+skanlite
4325+skrooge
4326+smb4k
4327+smuxi-frontend-gnome
4328+software-properties-gtk
4329+software-properties-kde
4330+specto
4331+speedcrunch
4332+stackapplet
4333+startupmanager
4334+stella
4335+step
4336+stopwatch
4337+sweeper
4338+synapse
4339+synaptic
4340+synce-trayicon
4341+sysinfo
4342+system-config-audit
4343+system-config-cluster
4344+system-config-date
4345+system-config-kickstart
4346+system-config-lvm
4347+system-config-samba
4348+systemsettings
4349+tasque
4350+taxbird
4351+tegaki-recognize
4352+teleport
4353+tellico
4354+terminator
4355+testdrive-gtk
4356+tex-guy
4357+texmaker
4358+thawab
4359+thunar
4360+tiger
4361+tilda
4362+tkdiff
4363+tracker-search-tool
4364+transfermii-gui
4365+treeline
4366+tritium
4367+turtleart
4368+tuxcmd
4369+uae
4370+ubuntu-edu-preschool
4371+ubuntu-edu-primary
4372+ubuntu-edu-secondary
4373+ubuntu-edu-tertiary
4374+ubuntu-restricted-extras
4375+ubuntuone-control-panel-gtk
4376+ubuntustudio-controls
4377+uck
4378+uim
4379+ukopp
4380+unetbootin
4381+unison2.27.57-gtk
4382+update-manager
4383+upnp-router-control
4384+usb-creator-gtk
4385+usb-creator-kde
4386+v4l2ucp
4387+vala-terminal
4388+verbiste
4389+viking
4390+virt-manager
4391+virtualbox
4392+vym
4393+wally
4394+wammu
4395+webboard
4396+wicd-kde
4397+wmgui
4398+wmitime
4399+worker
4400+workrave
4401+xarchiver
4402+xca
4403+xdiagnose
4404+xenwatch
4405+xfe
4406+xgnokii
4407+xiphos
4408+xiterm+thai
4409+xmonad
4410+xmotd
4411+xnc
4412+xoo
4413+xoscope
4414+xosview
4415+xsensors
4416+xubuntu-restricted-extras
4417+xul-ext-ubufox
4418+xvattr
4419+xvidcap
4420+yakuake
4421+yapet
4422+yate-qt4
4423+yelp
4424+zekr
4425+zita-at1
4426
4427=== added file 'data/category/profession'
4428--- data/category/profession 1970-01-01 00:00:00 +0000
4429+++ data/category/profession 2014-03-08 03:45:16 +0000
4430@@ -0,0 +1,184 @@
4431+achilles
4432+aeskulap
4433+amide
4434+avida-qt-viewer
4435+avogadro
4436+ballview
4437+bauble
4438+bibus
4439+bist
4440+bkchem
4441+blinken
4442+cadabra
4443+cantor
4444+caret
4445+carmetal
4446+celestia
4447+celestia-glut
4448+chemtool
4449+clustalx
4450+code-aster-gui
4451+coqide
4452+critterding
4453+ctsim
4454+drawxtl
4455+dx
4456+eagle
4457+easychem
4458+eficas
4459+electric
4460+emboss-explorer
4461+epigrass
4462+eqonomize
4463+euler
4464+extcalc
4465+extrema
4466+fastdnaml
4467+fityk
4468+freecad
4469+freediams
4470+freemat
4471+fsl-4.1
4472+fslview
4473+g3data
4474+gabedit
4475+galculator
4476+gambit
4477+gamgi
4478+garlic
4479+gausssum
4480+gdis
4481+gdpc
4482+geda-gattrib
4483+geda-gschem
4484+geda-xgsch2pcb
4485+gelemental
4486+genesis
4487+geomview
4488+gerbv
4489+ggobi
4490+ghkl
4491+glfer
4492+gmfsk
4493+gmsh
4494+gnusim8085
4495+gperiodic
4496+gpredict
4497+gpsk31
4498+grace
4499+graphmonkey
4500+graphthing
4501+gresistor
4502+gretl
4503+grinvin
4504+grisbi
4505+grpn
4506+gsmc
4507+gvb
4508+gwave
4509+gwyddion
4510+harpia
4511+homebank
4512+ifrit
4513+imagej
4514+imview
4515+itksnap
4516+jemboss
4517+jfractionlab
4518+k3dsurf
4519+kalgebra
4520+kalzium
4521+kayali
4522+kbruch
4523+kicad
4524+kig
4525+kile
4526+kitsune
4527+klog
4528+kmplot
4529+kseg
4530+kstars
4531+latexila
4532+librecad
4533+linpsk
4534+linsmith
4535+lybniz
4536+magnus
4537+massxpert
4538+mathomatic
4539+mcu8051ide
4540+melting-gui
4541+mmass
4542+model-builder
4543+mricron
4544+mrtrix
4545+netgen
4546+njplot
4547+octave3.2
4548+opencascade-draw
4549+openrocket
4550+openuniverse
4551+oregano
4552+ovito
4553+paraview
4554+paw++
4555+pcb
4556+perlprimer
4557+planets
4558+plotdrop
4559+praat
4560+pspp
4561+psychopy
4562+pymca
4563+pymol
4564+pyrocket
4565+python-ifeffit
4566+pythoncad
4567+qalculate-gtk
4568+qcad
4569+qelectrotech
4570+qgis
4571+qmk-groundstation
4572+qtdmm
4573+qtiplot
4574+qtoctave
4575+qucs
4576+rfdump
4577+rkward
4578+rlplot
4579+rocs
4580+sagcad
4581+scidavis
4582+scilab
4583+seaview
4584+sixpack
4585+snappea
4586+socnetv
4587+starplot
4588+stellarium
4589+survex-aven
4590+survex-svxedit
4591+sweethome3d
4592+tkgate
4593+tree-ppuzzle
4594+tree-puzzle
4595+treeviewx
4596+tucnak2
4597+twlog
4598+twpsk
4599+udav
4600+ugene
4601+viewmol
4602+weka
4603+wsjt
4604+wxbanker
4605+wxmaxima
4606+xdrawchem
4607+xdx
4608+xlog
4609+xmakemol
4610+xmaxima
4611+xtide
4612+ygraph
4613+z88
4614+zygrib
4615
4616=== added file 'data/category/recommend'
4617--- data/category/recommend 1970-01-01 00:00:00 +0000
4618+++ data/category/recommend 2014-03-08 03:45:16 +0000
4619@@ -0,0 +1,4 @@
4620+flashplugin-installer
4621+vlc
4622+openfetion
4623+virtualbox
4624
4625=== added file 'data/category/ubuntukylin'
4626--- data/category/ubuntukylin 1970-01-01 00:00:00 +0000
4627+++ data/category/ubuntukylin 2014-03-08 03:45:16 +0000
4628@@ -0,0 +1,4 @@
4629+flashplugin-installer
4630+vlc
4631+openfetion
4632+virtualbox
4633
4634=== removed file 'data/db.py'
4635--- data/db.py 2014-02-27 08:08:12 +0000
4636+++ data/db.py 1970-01-01 00:00:00 +0000
4637@@ -1,7 +0,0 @@
4638-#!/usr/bin/python
4639-# -*- coding: utf-8 -*-
4640-__author__ = 'Shine Huang'
4641-
4642-
4643-class DB:
4644- pass
4645\ No newline at end of file
4646
4647=== added directory 'data/icons'
4648=== added file 'data/icons/flashplugin-installer.png'
4649Binary files data/icons/flashplugin-installer.png 1970-01-01 00:00:00 +0000 and data/icons/flashplugin-installer.png 2014-03-08 03:45:16 +0000 differ
4650=== added file 'data/icons/kuaipan4uk.png'
4651Binary files data/icons/kuaipan4uk.png 1970-01-01 00:00:00 +0000 and data/icons/kuaipan4uk.png 2014-03-08 03:45:16 +0000 differ
4652=== added file 'data/icons/kugou.png'
4653Binary files data/icons/kugou.png 1970-01-01 00:00:00 +0000 and data/icons/kugou.png 2014-03-08 03:45:16 +0000 differ
4654=== added file 'data/icons/liaotian.png'
4655Binary files data/icons/liaotian.png 1970-01-01 00:00:00 +0000 and data/icons/liaotian.png 2014-03-08 03:45:16 +0000 differ
4656=== added file 'data/icons/lotus.png'
4657Binary files data/icons/lotus.png 1970-01-01 00:00:00 +0000 and data/icons/lotus.png 2014-03-08 03:45:16 +0000 differ
4658=== added file 'data/icons/lotus2.png'
4659Binary files data/icons/lotus2.png 1970-01-01 00:00:00 +0000 and data/icons/lotus2.png 2014-03-08 03:45:16 +0000 differ
4660=== added file 'data/icons/openfetion.png'
4661Binary files data/icons/openfetion.png 1970-01-01 00:00:00 +0000 and data/icons/openfetion.png 2014-03-08 03:45:16 +0000 differ
4662=== added file 'data/icons/pps.png'
4663Binary files data/icons/pps.png 1970-01-01 00:00:00 +0000 and data/icons/pps.png 2014-03-08 03:45:16 +0000 differ
4664=== added file 'data/icons/qq.png'
4665Binary files data/icons/qq.png 1970-01-01 00:00:00 +0000 and data/icons/qq.png 2014-03-08 03:45:16 +0000 differ
4666=== added file 'data/icons/thunder.png'
4667Binary files data/icons/thunder.png 1970-01-01 00:00:00 +0000 and data/icons/thunder.png 2014-03-08 03:45:16 +0000 differ
4668=== added file 'data/icons/virtualbox.png'
4669Binary files data/icons/virtualbox.png 1970-01-01 00:00:00 +0000 and data/icons/virtualbox.png 2014-03-08 03:45:16 +0000 differ
4670=== added file 'data/icons/virtualbox2.png'
4671Binary files data/icons/virtualbox2.png 1970-01-01 00:00:00 +0000 and data/icons/virtualbox2.png 2014-03-08 03:45:16 +0000 differ
4672=== added file 'data/icons/vlc.png'
4673Binary files data/icons/vlc.png 1970-01-01 00:00:00 +0000 and data/icons/vlc.png 2014-03-08 03:45:16 +0000 differ
4674=== added file 'data/icons/vlc2.png'
4675Binary files data/icons/vlc2.png 1970-01-01 00:00:00 +0000 and data/icons/vlc2.png 2014-03-08 03:45:16 +0000 differ
4676=== added file 'data/icons/wps.png'
4677Binary files data/icons/wps.png 1970-01-01 00:00:00 +0000 and data/icons/wps.png 2014-03-08 03:45:16 +0000 differ
4678=== added directory 'data/screenshots'
4679=== added file 'data/screenshots/fotoxx10.7-1_5042_small.png'
4680Binary files data/screenshots/fotoxx10.7-1_5042_small.png 1970-01-01 00:00:00 +0000 and data/screenshots/fotoxx10.7-1_5042_small.png 2014-03-08 03:45:16 +0000 differ
4681=== added file 'data/screenshots/kbibtex0.2.1-1_1827_small.png'
4682Binary files data/screenshots/kbibtex0.2.1-1_1827_small.png 1970-01-01 00:00:00 +0000 and data/screenshots/kbibtex0.2.1-1_1827_small.png 2014-03-08 03:45:16 +0000 differ
4683=== added file 'data/screenshots/openfetion2.2.1-2_7560_small.png'
4684Binary files data/screenshots/openfetion2.2.1-2_7560_small.png 1970-01-01 00:00:00 +0000 and data/screenshots/openfetion2.2.1-2_7560_small.png 2014-03-08 03:45:16 +0000 differ
4685=== added file 'data/screenshots/vlc0.8.6.h-5_66_small.png'
4686Binary files data/screenshots/vlc0.8.6.h-5_66_small.png 1970-01-01 00:00:00 +0000 and data/screenshots/vlc0.8.6.h-5_66_small.png 2014-03-08 03:45:16 +0000 differ
4687=== added file 'data/screenshots/vlc1.1.3_4835_small.png'
4688Binary files data/screenshots/vlc1.1.3_4835_small.png 1970-01-01 00:00:00 +0000 and data/screenshots/vlc1.1.3_4835_small.png 2014-03-08 03:45:16 +0000 differ
4689=== added file 'data/screenshots/vlc2.0.1-4_9368_small.png'
4690Binary files data/screenshots/vlc2.0.1-4_9368_small.png 1970-01-01 00:00:00 +0000 and data/screenshots/vlc2.0.1-4_9368_small.png 2014-03-08 03:45:16 +0000 differ
4691=== added directory 'data/tmpicons'
4692=== added file 'data/tmpicons/3dchess.png'
4693Binary files data/tmpicons/3dchess.png 1970-01-01 00:00:00 +0000 and data/tmpicons/3dchess.png 2014-03-08 03:45:16 +0000 differ
4694=== added file 'data/tmpicons/3depict.png'
4695Binary files data/tmpicons/3depict.png 1970-01-01 00:00:00 +0000 and data/tmpicons/3depict.png 2014-03-08 03:45:16 +0000 differ
4696=== added file 'data/tmpicons/ASUC-v1.2.01_20111101.png'
4697Binary files data/tmpicons/ASUC-v1.2.01_20111101.png 1970-01-01 00:00:00 +0000 and data/tmpicons/ASUC-v1.2.01_20111101.png 2014-03-08 03:45:16 +0000 differ
4698=== added file 'data/tmpicons/ASUC.png'
4699Binary files data/tmpicons/ASUC.png 1970-01-01 00:00:00 +0000 and data/tmpicons/ASUC.png 2014-03-08 03:45:16 +0000 differ
4700=== added file 'data/tmpicons/PyQt4-devel.png'
4701Binary files data/tmpicons/PyQt4-devel.png 1970-01-01 00:00:00 +0000 and data/tmpicons/PyQt4-devel.png 2014-03-08 03:45:16 +0000 differ
4702=== added file 'data/tmpicons/a7xpg.png'
4703Binary files data/tmpicons/a7xpg.png 1970-01-01 00:00:00 +0000 and data/tmpicons/a7xpg.png 2014-03-08 03:45:16 +0000 differ
4704=== added file 'data/tmpicons/abe.png'
4705Binary files data/tmpicons/abe.png 1970-01-01 00:00:00 +0000 and data/tmpicons/abe.png 2014-03-08 03:45:16 +0000 differ
4706=== added file 'data/tmpicons/abiword.png'
4707Binary files data/tmpicons/abiword.png 1970-01-01 00:00:00 +0000 and data/tmpicons/abiword.png 2014-03-08 03:45:16 +0000 differ
4708=== added file 'data/tmpicons/abraca.png'
4709Binary files data/tmpicons/abraca.png 1970-01-01 00:00:00 +0000 and data/tmpicons/abraca.png 2014-03-08 03:45:16 +0000 differ
4710=== added file 'data/tmpicons/abuse.png'
4711Binary files data/tmpicons/abuse.png 1970-01-01 00:00:00 +0000 and data/tmpicons/abuse.png 2014-03-08 03:45:16 +0000 differ
4712=== added file 'data/tmpicons/accerciser.png'
4713Binary files data/tmpicons/accerciser.png 1970-01-01 00:00:00 +0000 and data/tmpicons/accerciser.png 2014-03-08 03:45:16 +0000 differ
4714=== added file 'data/tmpicons/acetino2.png'
4715Binary files data/tmpicons/acetino2.png 1970-01-01 00:00:00 +0000 and data/tmpicons/acetino2.png 2014-03-08 03:45:16 +0000 differ
4716=== added file 'data/tmpicons/acetoneiso.png'
4717Binary files data/tmpicons/acetoneiso.png 1970-01-01 00:00:00 +0000 and data/tmpicons/acetoneiso.png 2014-03-08 03:45:16 +0000 differ
4718=== added file 'data/tmpicons/achilles.png'
4719Binary files data/tmpicons/achilles.png 1970-01-01 00:00:00 +0000 and data/tmpicons/achilles.png 2014-03-08 03:45:16 +0000 differ
4720=== added file 'data/tmpicons/acidrip.png'
4721Binary files data/tmpicons/acidrip.png 1970-01-01 00:00:00 +0000 and data/tmpicons/acidrip.png 2014-03-08 03:45:16 +0000 differ
4722=== added file 'data/tmpicons/aclock.app.png'
4723Binary files data/tmpicons/aclock.app.png 1970-01-01 00:00:00 +0000 and data/tmpicons/aclock.app.png 2014-03-08 03:45:16 +0000 differ
4724=== added file 'data/tmpicons/acm.png'
4725Binary files data/tmpicons/acm.png 1970-01-01 00:00:00 +0000 and data/tmpicons/acm.png 2014-03-08 03:45:16 +0000 differ
4726=== added file 'data/tmpicons/aconnectgui.png'
4727Binary files data/tmpicons/aconnectgui.png 1970-01-01 00:00:00 +0000 and data/tmpicons/aconnectgui.png 2014-03-08 03:45:16 +0000 differ
4728=== added file 'data/tmpicons/activity-etoys.png'
4729Binary files data/tmpicons/activity-etoys.png 1970-01-01 00:00:00 +0000 and data/tmpicons/activity-etoys.png 2014-03-08 03:45:16 +0000 differ
4730=== added file 'data/tmpicons/adanaxisgpl.png'
4731Binary files data/tmpicons/adanaxisgpl.png 1970-01-01 00:00:00 +0000 and data/tmpicons/adanaxisgpl.png 2014-03-08 03:45:16 +0000 differ
4732=== added file 'data/tmpicons/adblock-plus.png'
4733Binary files data/tmpicons/adblock-plus.png 1970-01-01 00:00:00 +0000 and data/tmpicons/adblock-plus.png 2014-03-08 03:45:16 +0000 differ
4734=== added file 'data/tmpicons/adobeflashplugin.png'
4735Binary files data/tmpicons/adobeflashplugin.png 1970-01-01 00:00:00 +0000 and data/tmpicons/adobeflashplugin.png 2014-03-08 03:45:16 +0000 differ
4736=== added file 'data/tmpicons/adonthell.png'
4737Binary files data/tmpicons/adonthell.png 1970-01-01 00:00:00 +0000 and data/tmpicons/adonthell.png 2014-03-08 03:45:16 +0000 differ
4738=== added file 'data/tmpicons/advancedcaching.png'
4739Binary files data/tmpicons/advancedcaching.png 1970-01-01 00:00:00 +0000 and data/tmpicons/advancedcaching.png 2014-03-08 03:45:16 +0000 differ
4740=== added file 'data/tmpicons/aeolus.png'
4741Binary files data/tmpicons/aeolus.png 1970-01-01 00:00:00 +0000 and data/tmpicons/aeolus.png 2014-03-08 03:45:16 +0000 differ
4742=== added file 'data/tmpicons/aeskulap.png'
4743Binary files data/tmpicons/aeskulap.png 1970-01-01 00:00:00 +0000 and data/tmpicons/aeskulap.png 2014-03-08 03:45:16 +0000 differ
4744=== added file 'data/tmpicons/agave.png'
4745Binary files data/tmpicons/agave.png 1970-01-01 00:00:00 +0000 and data/tmpicons/agave.png 2014-03-08 03:45:16 +0000 differ
4746=== added file 'data/tmpicons/airstrike.png'
4747Binary files data/tmpicons/airstrike.png 1970-01-01 00:00:00 +0000 and data/tmpicons/airstrike.png 2014-03-08 03:45:16 +0000 differ
4748=== added file 'data/tmpicons/aisleriot.png'
4749Binary files data/tmpicons/aisleriot.png 1970-01-01 00:00:00 +0000 and data/tmpicons/aisleriot.png 2014-03-08 03:45:16 +0000 differ
4750=== added file 'data/tmpicons/akregator.png'
4751Binary files data/tmpicons/akregator.png 1970-01-01 00:00:00 +0000 and data/tmpicons/akregator.png 2014-03-08 03:45:16 +0000 differ
4752=== added file 'data/tmpicons/alacarte.png'
4753Binary files data/tmpicons/alacarte.png 1970-01-01 00:00:00 +0000 and data/tmpicons/alacarte.png 2014-03-08 03:45:16 +0000 differ
4754=== added file 'data/tmpicons/alarm-clock-applet.png'
4755Binary files data/tmpicons/alarm-clock-applet.png 1970-01-01 00:00:00 +0000 and data/tmpicons/alarm-clock-applet.png 2014-03-08 03:45:16 +0000 differ
4756=== added file 'data/tmpicons/alarm-clock.png'
4757Binary files data/tmpicons/alarm-clock.png 1970-01-01 00:00:00 +0000 and data/tmpicons/alarm-clock.png 2014-03-08 03:45:16 +0000 differ
4758=== added file 'data/tmpicons/albumshaper.png'
4759Binary files data/tmpicons/albumshaper.png 1970-01-01 00:00:00 +0000 and data/tmpicons/albumshaper.png 2014-03-08 03:45:16 +0000 differ
4760=== added file 'data/tmpicons/alc.png'
4761Binary files data/tmpicons/alc.png 1970-01-01 00:00:00 +0000 and data/tmpicons/alc.png 2014-03-08 03:45:16 +0000 differ
4762=== added file 'data/tmpicons/alex4.png'
4763Binary files data/tmpicons/alex4.png 1970-01-01 00:00:00 +0000 and data/tmpicons/alex4.png 2014-03-08 03:45:16 +0000 differ
4764=== added file 'data/tmpicons/alexandria.png'
4765Binary files data/tmpicons/alexandria.png 1970-01-01 00:00:00 +0000 and data/tmpicons/alexandria.png 2014-03-08 03:45:16 +0000 differ
4766=== added file 'data/tmpicons/alien-arena.png'
4767Binary files data/tmpicons/alien-arena.png 1970-01-01 00:00:00 +0000 and data/tmpicons/alien-arena.png 2014-03-08 03:45:16 +0000 differ
4768=== added file 'data/tmpicons/alienblaster.png'
4769Binary files data/tmpicons/alienblaster.png 1970-01-01 00:00:00 +0000 and data/tmpicons/alienblaster.png 2014-03-08 03:45:16 +0000 differ
4770=== added file 'data/tmpicons/all-in-one-sidebar.png'
4771Binary files data/tmpicons/all-in-one-sidebar.png 1970-01-01 00:00:00 +0000 and data/tmpicons/all-in-one-sidebar.png 2014-03-08 03:45:16 +0000 differ
4772=== added file 'data/tmpicons/alleyoop.png'
4773Binary files data/tmpicons/alleyoop.png 1970-01-01 00:00:00 +0000 and data/tmpicons/alleyoop.png 2014-03-08 03:45:16 +0000 differ
4774=== added file 'data/tmpicons/alltray.png'
4775Binary files data/tmpicons/alltray.png 1970-01-01 00:00:00 +0000 and data/tmpicons/alltray.png 2014-03-08 03:45:16 +0000 differ
4776=== added file 'data/tmpicons/almanah.png'
4777Binary files data/tmpicons/almanah.png 1970-01-01 00:00:00 +0000 and data/tmpicons/almanah.png 2014-03-08 03:45:16 +0000 differ
4778=== added file 'data/tmpicons/alsamixergui.png'
4779Binary files data/tmpicons/alsamixergui.png 1970-01-01 00:00:00 +0000 and data/tmpicons/alsamixergui.png 2014-03-08 03:45:16 +0000 differ
4780=== added file 'data/tmpicons/amarok.png'
4781Binary files data/tmpicons/amarok.png 1970-01-01 00:00:00 +0000 and data/tmpicons/amarok.png 2014-03-08 03:45:16 +0000 differ
4782=== added file 'data/tmpicons/amide.png'
4783Binary files data/tmpicons/amide.png 1970-01-01 00:00:00 +0000 and data/tmpicons/amide.png 2014-03-08 03:45:16 +0000 differ
4784=== added file 'data/tmpicons/amide_logo.png'
4785Binary files data/tmpicons/amide_logo.png 1970-01-01 00:00:00 +0000 and data/tmpicons/amide_logo.png 2014-03-08 03:45:16 +0000 differ
4786=== added file 'data/tmpicons/amor.png'
4787Binary files data/tmpicons/amor.png 1970-01-01 00:00:00 +0000 and data/tmpicons/amor.png 2014-03-08 03:45:16 +0000 differ
4788=== added file 'data/tmpicons/amph.png'
4789Binary files data/tmpicons/amph.png 1970-01-01 00:00:00 +0000 and data/tmpicons/amph.png 2014-03-08 03:45:16 +0000 differ
4790=== added file 'data/tmpicons/ams.png'
4791Binary files data/tmpicons/ams.png 1970-01-01 00:00:00 +0000 and data/tmpicons/ams.png 2014-03-08 03:45:16 +0000 differ
4792=== added file 'data/tmpicons/amsn.png'
4793Binary files data/tmpicons/amsn.png 1970-01-01 00:00:00 +0000 and data/tmpicons/amsn.png 2014-03-08 03:45:16 +0000 differ
4794=== added file 'data/tmpicons/amsynth.png'
4795Binary files data/tmpicons/amsynth.png 1970-01-01 00:00:00 +0000 and data/tmpicons/amsynth.png 2014-03-08 03:45:16 +0000 differ
4796=== added file 'data/tmpicons/amule.png'
4797Binary files data/tmpicons/amule.png 1970-01-01 00:00:00 +0000 and data/tmpicons/amule.png 2014-03-08 03:45:16 +0000 differ
4798=== added file 'data/tmpicons/amulegui.png'
4799Binary files data/tmpicons/amulegui.png 1970-01-01 00:00:00 +0000 and data/tmpicons/amulegui.png 2014-03-08 03:45:16 +0000 differ
4800=== added file 'data/tmpicons/anagramarama.png'
4801Binary files data/tmpicons/anagramarama.png 1970-01-01 00:00:00 +0000 and data/tmpicons/anagramarama.png 2014-03-08 03:45:16 +0000 differ
4802=== added file 'data/tmpicons/angrydd.png'
4803Binary files data/tmpicons/angrydd.png 1970-01-01 00:00:00 +0000 and data/tmpicons/angrydd.png 2014-03-08 03:45:16 +0000 differ
4804=== added file 'data/tmpicons/anjuta.png'
4805Binary files data/tmpicons/anjuta.png 1970-01-01 00:00:00 +0000 and data/tmpicons/anjuta.png 2014-03-08 03:45:16 +0000 differ
4806=== added file 'data/tmpicons/anki.png'
4807Binary files data/tmpicons/anki.png 1970-01-01 00:00:00 +0000 and data/tmpicons/anki.png 2014-03-08 03:45:16 +0000 differ
4808=== added file 'data/tmpicons/anymeal.png'
4809Binary files data/tmpicons/anymeal.png 1970-01-01 00:00:00 +0000 and data/tmpicons/anymeal.png 2014-03-08 03:45:16 +0000 differ
4810=== added file 'data/tmpicons/applets-screenshooter.png'
4811Binary files data/tmpicons/applets-screenshooter.png 1970-01-01 00:00:00 +0000 and data/tmpicons/applets-screenshooter.png 2014-03-08 03:45:16 +0000 differ
4812=== added file 'data/tmpicons/application-x-boats.png'
4813Binary files data/tmpicons/application-x-boats.png 1970-01-01 00:00:00 +0000 and data/tmpicons/application-x-boats.png 2014-03-08 03:45:16 +0000 differ
4814=== added file 'data/tmpicons/application-x-kcollectd.png'
4815Binary files data/tmpicons/application-x-kcollectd.png 1970-01-01 00:00:00 +0000 and data/tmpicons/application-x-kcollectd.png 2014-03-08 03:45:16 +0000 differ
4816=== added file 'data/tmpicons/application-x-kmediafactory.png'
4817Binary files data/tmpicons/application-x-kmediafactory.png 1970-01-01 00:00:00 +0000 and data/tmpicons/application-x-kmediafactory.png 2014-03-08 03:45:16 +0000 differ
4818=== added file 'data/tmpicons/aptoncd.png'
4819Binary files data/tmpicons/aptoncd.png 1970-01-01 00:00:00 +0000 and data/tmpicons/aptoncd.png 2014-03-08 03:45:16 +0000 differ
4820=== added file 'data/tmpicons/apvlv.png'
4821Binary files data/tmpicons/apvlv.png 1970-01-01 00:00:00 +0000 and data/tmpicons/apvlv.png 2014-03-08 03:45:16 +0000 differ
4822=== added file 'data/tmpicons/aqemu.png'
4823Binary files data/tmpicons/aqemu.png 1970-01-01 00:00:00 +0000 and data/tmpicons/aqemu.png 2014-03-08 03:45:16 +0000 differ
4824=== added file 'data/tmpicons/aqsis.png'
4825Binary files data/tmpicons/aqsis.png 1970-01-01 00:00:00 +0000 and data/tmpicons/aqsis.png 2014-03-08 03:45:16 +0000 differ
4826=== added file 'data/tmpicons/aqualung.png'
4827Binary files data/tmpicons/aqualung.png 1970-01-01 00:00:00 +0000 and data/tmpicons/aqualung.png 2014-03-08 03:45:16 +0000 differ
4828=== added file 'data/tmpicons/aranym.png'
4829Binary files data/tmpicons/aranym.png 1970-01-01 00:00:00 +0000 and data/tmpicons/aranym.png 2014-03-08 03:45:16 +0000 differ
4830=== added file 'data/tmpicons/arcjobtool.png'
4831Binary files data/tmpicons/arcjobtool.png 1970-01-01 00:00:00 +0000 and data/tmpicons/arcjobtool.png 2014-03-08 03:45:16 +0000 differ
4832=== added file 'data/tmpicons/ardour.png'
4833Binary files data/tmpicons/ardour.png 1970-01-01 00:00:00 +0000 and data/tmpicons/ardour.png 2014-03-08 03:45:16 +0000 differ
4834=== added file 'data/tmpicons/arduino.png'
4835Binary files data/tmpicons/arduino.png 1970-01-01 00:00:00 +0000 and data/tmpicons/arduino.png 2014-03-08 03:45:16 +0000 differ
4836=== added file 'data/tmpicons/ario.png'
4837Binary files data/tmpicons/ario.png 1970-01-01 00:00:00 +0000 and data/tmpicons/ario.png 2014-03-08 03:45:16 +0000 differ
4838=== added file 'data/tmpicons/arista.png'
4839Binary files data/tmpicons/arista.png 1970-01-01 00:00:00 +0000 and data/tmpicons/arista.png 2014-03-08 03:45:16 +0000 differ
4840=== added file 'data/tmpicons/ark.png'
4841Binary files data/tmpicons/ark.png 1970-01-01 00:00:00 +0000 and data/tmpicons/ark.png 2014-03-08 03:45:16 +0000 differ
4842=== added file 'data/tmpicons/armagetronad.png'
4843Binary files data/tmpicons/armagetronad.png 1970-01-01 00:00:00 +0000 and data/tmpicons/armagetronad.png 2014-03-08 03:45:16 +0000 differ
4844=== added file 'data/tmpicons/arora.png'
4845Binary files data/tmpicons/arora.png 1970-01-01 00:00:00 +0000 and data/tmpicons/arora.png 2014-03-08 03:45:16 +0000 differ
4846=== added file 'data/tmpicons/artemis.png'
4847Binary files data/tmpicons/artemis.png 1970-01-01 00:00:00 +0000 and data/tmpicons/artemis.png 2014-03-08 03:45:16 +0000 differ
4848=== added file 'data/tmpicons/artha.png'
4849Binary files data/tmpicons/artha.png 1970-01-01 00:00:00 +0000 and data/tmpicons/artha.png 2014-03-08 03:45:16 +0000 differ
4850=== added file 'data/tmpicons/asc.png'
4851Binary files data/tmpicons/asc.png 1970-01-01 00:00:00 +0000 and data/tmpicons/asc.png 2014-03-08 03:45:16 +0000 differ
4852=== added file 'data/tmpicons/assaultcube.png'
4853Binary files data/tmpicons/assaultcube.png 1970-01-01 00:00:00 +0000 and data/tmpicons/assaultcube.png 2014-03-08 03:45:16 +0000 differ
4854=== added file 'data/tmpicons/assistant.png'
4855Binary files data/tmpicons/assistant.png 1970-01-01 00:00:00 +0000 and data/tmpicons/assistant.png 2014-03-08 03:45:16 +0000 differ
4856=== added file 'data/tmpicons/assogiate.png'
4857Binary files data/tmpicons/assogiate.png 1970-01-01 00:00:00 +0000 and data/tmpicons/assogiate.png 2014-03-08 03:45:16 +0000 differ
4858=== added file 'data/tmpicons/astk.png'
4859Binary files data/tmpicons/astk.png 1970-01-01 00:00:00 +0000 and data/tmpicons/astk.png 2014-03-08 03:45:16 +0000 differ
4860=== added file 'data/tmpicons/asunder.png'
4861Binary files data/tmpicons/asunder.png 1970-01-01 00:00:00 +0000 and data/tmpicons/asunder.png 2014-03-08 03:45:16 +0000 differ
4862=== added file 'data/tmpicons/asylum.png'
4863Binary files data/tmpicons/asylum.png 1970-01-01 00:00:00 +0000 and data/tmpicons/asylum.png 2014-03-08 03:45:16 +0000 differ
4864=== added file 'data/tmpicons/atanks.png'
4865Binary files data/tmpicons/atanks.png 1970-01-01 00:00:00 +0000 and data/tmpicons/atanks.png 2014-03-08 03:45:16 +0000 differ
4866=== added file 'data/tmpicons/athena.png'
4867Binary files data/tmpicons/athena.png 1970-01-01 00:00:00 +0000 and data/tmpicons/athena.png 2014-03-08 03:45:16 +0000 differ
4868=== added file 'data/tmpicons/atris.png'
4869Binary files data/tmpicons/atris.png 1970-01-01 00:00:00 +0000 and data/tmpicons/atris.png 2014-03-08 03:45:16 +0000 differ
4870=== added file 'data/tmpicons/audacious.png'
4871Binary files data/tmpicons/audacious.png 1970-01-01 00:00:00 +0000 and data/tmpicons/audacious.png 2014-03-08 03:45:16 +0000 differ
4872=== added file 'data/tmpicons/audacity.png'
4873Binary files data/tmpicons/audacity.png 1970-01-01 00:00:00 +0000 and data/tmpicons/audacity.png 2014-03-08 03:45:16 +0000 differ
4874=== added file 'data/tmpicons/audex.png'
4875Binary files data/tmpicons/audex.png 1970-01-01 00:00:00 +0000 and data/tmpicons/audex.png 2014-03-08 03:45:16 +0000 differ
4876=== added file 'data/tmpicons/audio-x-generic.png'
4877Binary files data/tmpicons/audio-x-generic.png 1970-01-01 00:00:00 +0000 and data/tmpicons/audio-x-generic.png 2014-03-08 03:45:16 +0000 differ
4878=== added file 'data/tmpicons/avant-window-navigator.png'
4879Binary files data/tmpicons/avant-window-navigator.png 1970-01-01 00:00:00 +0000 and data/tmpicons/avant-window-navigator.png 2014-03-08 03:45:16 +0000 differ
4880=== added file 'data/tmpicons/aven.png'
4881Binary files data/tmpicons/aven.png 1970-01-01 00:00:00 +0000 and data/tmpicons/aven.png 2014-03-08 03:45:16 +0000 differ
4882=== added file 'data/tmpicons/avida.png'
4883Binary files data/tmpicons/avida.png 1970-01-01 00:00:00 +0000 and data/tmpicons/avida.png 2014-03-08 03:45:16 +0000 differ
4884=== added file 'data/tmpicons/avidemux-qt.png'
4885Binary files data/tmpicons/avidemux-qt.png 1970-01-01 00:00:00 +0000 and data/tmpicons/avidemux-qt.png 2014-03-08 03:45:16 +0000 differ
4886=== added file 'data/tmpicons/avogadro.png'
4887Binary files data/tmpicons/avogadro.png 1970-01-01 00:00:00 +0000 and data/tmpicons/avogadro.png 2014-03-08 03:45:16 +0000 differ
4888=== added file 'data/tmpicons/awn-settings.png'
4889Binary files data/tmpicons/awn-settings.png 1970-01-01 00:00:00 +0000 and data/tmpicons/awn-settings.png 2014-03-08 03:45:16 +0000 differ
4890=== added file 'data/tmpicons/ayttm.png'
4891Binary files data/tmpicons/ayttm.png 1970-01-01 00:00:00 +0000 and data/tmpicons/ayttm.png 2014-03-08 03:45:16 +0000 differ
4892=== added file 'data/tmpicons/azureus.png'
4893Binary files data/tmpicons/azureus.png 1970-01-01 00:00:00 +0000 and data/tmpicons/azureus.png 2014-03-08 03:45:16 +0000 differ
4894=== added file 'data/tmpicons/babiloo.png'
4895Binary files data/tmpicons/babiloo.png 1970-01-01 00:00:00 +0000 and data/tmpicons/babiloo.png 2014-03-08 03:45:16 +0000 differ
4896=== added file 'data/tmpicons/balazar.png'
4897Binary files data/tmpicons/balazar.png 1970-01-01 00:00:00 +0000 and data/tmpicons/balazar.png 2014-03-08 03:45:16 +0000 differ
4898=== added file 'data/tmpicons/balazarbrothers.png'
4899Binary files data/tmpicons/balazarbrothers.png 1970-01-01 00:00:00 +0000 and data/tmpicons/balazarbrothers.png 2014-03-08 03:45:16 +0000 differ
4900=== added file 'data/tmpicons/balder2d.png'
4901Binary files data/tmpicons/balder2d.png 1970-01-01 00:00:00 +0000 and data/tmpicons/balder2d.png 2014-03-08 03:45:16 +0000 differ
4902=== added file 'data/tmpicons/ballview.png'
4903Binary files data/tmpicons/ballview.png 1970-01-01 00:00:00 +0000 and data/tmpicons/ballview.png 2014-03-08 03:45:16 +0000 differ
4904=== added file 'data/tmpicons/ballz.png'
4905Binary files data/tmpicons/ballz.png 1970-01-01 00:00:00 +0000 and data/tmpicons/ballz.png 2014-03-08 03:45:16 +0000 differ
4906=== added file 'data/tmpicons/balsa.png'
4907Binary files data/tmpicons/balsa.png 1970-01-01 00:00:00 +0000 and data/tmpicons/balsa.png 2014-03-08 03:45:16 +0000 differ
4908=== added file 'data/tmpicons/bangarang.png'
4909Binary files data/tmpicons/bangarang.png 1970-01-01 00:00:00 +0000 and data/tmpicons/bangarang.png 2014-03-08 03:45:16 +0000 differ
4910=== added file 'data/tmpicons/banshee.png'
4911Binary files data/tmpicons/banshee.png 1970-01-01 00:00:00 +0000 and data/tmpicons/banshee.png 2014-03-08 03:45:16 +0000 differ
4912=== added file 'data/tmpicons/baobab.png'
4913Binary files data/tmpicons/baobab.png 1970-01-01 00:00:00 +0000 and data/tmpicons/baobab.png 2014-03-08 03:45:16 +0000 differ
4914=== added file 'data/tmpicons/bareftp.png'
4915Binary files data/tmpicons/bareftp.png 1970-01-01 00:00:00 +0000 and data/tmpicons/bareftp.png 2014-03-08 03:45:16 +0000 differ
4916=== added file 'data/tmpicons/barrage.png'
4917Binary files data/tmpicons/barrage.png 1970-01-01 00:00:00 +0000 and data/tmpicons/barrage.png 2014-03-08 03:45:16 +0000 differ
4918=== added file 'data/tmpicons/basic256.png'
4919Binary files data/tmpicons/basic256.png 1970-01-01 00:00:00 +0000 and data/tmpicons/basic256.png 2014-03-08 03:45:16 +0000 differ
4920=== added file 'data/tmpicons/basket.png'
4921Binary files data/tmpicons/basket.png 1970-01-01 00:00:00 +0000 and data/tmpicons/basket.png 2014-03-08 03:45:16 +0000 differ
4922=== added file 'data/tmpicons/battery-stats.png'
4923Binary files data/tmpicons/battery-stats.png 1970-01-01 00:00:00 +0000 and data/tmpicons/battery-stats.png 2014-03-08 03:45:16 +0000 differ
4924=== added file 'data/tmpicons/battleball.png'
4925Binary files data/tmpicons/battleball.png 1970-01-01 00:00:00 +0000 and data/tmpicons/battleball.png 2014-03-08 03:45:16 +0000 differ
4926=== added file 'data/tmpicons/bauble.png'
4927Binary files data/tmpicons/bauble.png 1970-01-01 00:00:00 +0000 and data/tmpicons/bauble.png 2014-03-08 03:45:16 +0000 differ
4928=== added file 'data/tmpicons/beast.png'
4929Binary files data/tmpicons/beast.png 1970-01-01 00:00:00 +0000 and data/tmpicons/beast.png 2014-03-08 03:45:16 +0000 differ
4930=== added file 'data/tmpicons/beer-mini.png'
4931Binary files data/tmpicons/beer-mini.png 1970-01-01 00:00:00 +0000 and data/tmpicons/beer-mini.png 2014-03-08 03:45:16 +0000 differ
4932=== added file 'data/tmpicons/beneath-a-steel-sky.png'
4933Binary files data/tmpicons/beneath-a-steel-sky.png 1970-01-01 00:00:00 +0000 and data/tmpicons/beneath-a-steel-sky.png 2014-03-08 03:45:16 +0000 differ
4934=== added file 'data/tmpicons/berusky.png'
4935Binary files data/tmpicons/berusky.png 1970-01-01 00:00:00 +0000 and data/tmpicons/berusky.png 2014-03-08 03:45:16 +0000 differ
4936=== added file 'data/tmpicons/bibledit.png'
4937Binary files data/tmpicons/bibledit.png 1970-01-01 00:00:00 +0000 and data/tmpicons/bibledit.png 2014-03-08 03:45:16 +0000 differ
4938=== added file 'data/tmpicons/biblememorizer.png'
4939Binary files data/tmpicons/biblememorizer.png 1970-01-01 00:00:00 +0000 and data/tmpicons/biblememorizer.png 2014-03-08 03:45:16 +0000 differ
4940=== added file 'data/tmpicons/bibletime.png'
4941Binary files data/tmpicons/bibletime.png 1970-01-01 00:00:00 +0000 and data/tmpicons/bibletime.png 2014-03-08 03:45:16 +0000 differ
4942=== added file 'data/tmpicons/bibus.png'
4943Binary files data/tmpicons/bibus.png 1970-01-01 00:00:00 +0000 and data/tmpicons/bibus.png 2014-03-08 03:45:16 +0000 differ
4944=== added file 'data/tmpicons/billard-gl.png'
4945Binary files data/tmpicons/billard-gl.png 1970-01-01 00:00:00 +0000 and data/tmpicons/billard-gl.png 2014-03-08 03:45:16 +0000 differ
4946=== added file 'data/tmpicons/biloba.png'
4947Binary files data/tmpicons/biloba.png 1970-01-01 00:00:00 +0000 and data/tmpicons/biloba.png 2014-03-08 03:45:16 +0000 differ
4948=== added file 'data/tmpicons/biniax2.png'
4949Binary files data/tmpicons/biniax2.png 1970-01-01 00:00:00 +0000 and data/tmpicons/biniax2.png 2014-03-08 03:45:16 +0000 differ
4950=== added file 'data/tmpicons/biococoa.app.png'
4951Binary files data/tmpicons/biococoa.app.png 1970-01-01 00:00:00 +0000 and data/tmpicons/biococoa.app.png 2014-03-08 03:45:16 +0000 differ
4952=== added file 'data/tmpicons/bist.png'
4953Binary files data/tmpicons/bist.png 1970-01-01 00:00:00 +0000 and data/tmpicons/bist.png 2014-03-08 03:45:16 +0000 differ
4954=== added file 'data/tmpicons/bitmeter.png'
4955Binary files data/tmpicons/bitmeter.png 1970-01-01 00:00:00 +0000 and data/tmpicons/bitmeter.png 2014-03-08 03:45:16 +0000 differ
4956=== added file 'data/tmpicons/bitpim.png'
4957Binary files data/tmpicons/bitpim.png 1970-01-01 00:00:00 +0000 and data/tmpicons/bitpim.png 2014-03-08 03:45:16 +0000 differ
4958=== added file 'data/tmpicons/bitstormlite.png'
4959Binary files data/tmpicons/bitstormlite.png 1970-01-01 00:00:00 +0000 and data/tmpicons/bitstormlite.png 2014-03-08 03:45:16 +0000 differ
4960=== added file 'data/tmpicons/bittornado.png'
4961Binary files data/tmpicons/bittornado.png 1970-01-01 00:00:00 +0000 and data/tmpicons/bittornado.png 2014-03-08 03:45:16 +0000 differ
4962=== added file 'data/tmpicons/bkchem.png'
4963Binary files data/tmpicons/bkchem.png 1970-01-01 00:00:00 +0000 and data/tmpicons/bkchem.png 2014-03-08 03:45:16 +0000 differ
4964=== added file 'data/tmpicons/black-box.png'
4965Binary files data/tmpicons/black-box.png 1970-01-01 00:00:00 +0000 and data/tmpicons/black-box.png 2014-03-08 03:45:16 +0000 differ
4966=== added file 'data/tmpicons/blackboxgame.png'
4967Binary files data/tmpicons/blackboxgame.png 1970-01-01 00:00:00 +0000 and data/tmpicons/blackboxgame.png 2014-03-08 03:45:16 +0000 differ
4968=== added file 'data/tmpicons/blam.png'
4969Binary files data/tmpicons/blam.png 1970-01-01 00:00:00 +0000 and data/tmpicons/blam.png 2014-03-08 03:45:16 +0000 differ
4970=== added file 'data/tmpicons/bleachbit.png'
4971Binary files data/tmpicons/bleachbit.png 1970-01-01 00:00:00 +0000 and data/tmpicons/bleachbit.png 2014-03-08 03:45:16 +0000 differ
4972=== added file 'data/tmpicons/blender.png'
4973Binary files data/tmpicons/blender.png 1970-01-01 00:00:00 +0000 and data/tmpicons/blender.png 2014-03-08 03:45:16 +0000 differ
4974=== added file 'data/tmpicons/bless.png'
4975Binary files data/tmpicons/bless.png 1970-01-01 00:00:00 +0000 and data/tmpicons/bless.png 2014-03-08 03:45:16 +0000 differ
4976=== added file 'data/tmpicons/blinken.png'
4977Binary files data/tmpicons/blinken.png 1970-01-01 00:00:00 +0000 and data/tmpicons/blinken.png 2014-03-08 03:45:16 +0000 differ
4978=== added file 'data/tmpicons/blobandconquer.png'
4979Binary files data/tmpicons/blobandconquer.png 1970-01-01 00:00:00 +0000 and data/tmpicons/blobandconquer.png 2014-03-08 03:45:16 +0000 differ
4980=== added file 'data/tmpicons/blobby.png'
4981Binary files data/tmpicons/blobby.png 1970-01-01 00:00:00 +0000 and data/tmpicons/blobby.png 2014-03-08 03:45:16 +0000 differ
4982=== added file 'data/tmpicons/bloboats.png'
4983Binary files data/tmpicons/bloboats.png 1970-01-01 00:00:00 +0000 and data/tmpicons/bloboats.png 2014-03-08 03:45:16 +0000 differ
4984=== added file 'data/tmpicons/blobwars.png'
4985Binary files data/tmpicons/blobwars.png 1970-01-01 00:00:00 +0000 and data/tmpicons/blobwars.png 2014-03-08 03:45:16 +0000 differ
4986=== added file 'data/tmpicons/blockattack.png'
4987Binary files data/tmpicons/blockattack.png 1970-01-01 00:00:00 +0000 and data/tmpicons/blockattack.png 2014-03-08 03:45:16 +0000 differ
4988=== added file 'data/tmpicons/blockout2.png'
4989Binary files data/tmpicons/blockout2.png 1970-01-01 00:00:00 +0000 and data/tmpicons/blockout2.png 2014-03-08 03:45:16 +0000 differ
4990=== added file 'data/tmpicons/blocks-of-the-undead.png'
4991Binary files data/tmpicons/blocks-of-the-undead.png 1970-01-01 00:00:00 +0000 and data/tmpicons/blocks-of-the-undead.png 2014-03-08 03:45:16 +0000 differ
4992=== added file 'data/tmpicons/blogilo.png'
4993Binary files data/tmpicons/blogilo.png 1970-01-01 00:00:00 +0000 and data/tmpicons/blogilo.png 2014-03-08 03:45:16 +0000 differ
4994=== added file 'data/tmpicons/blogtk.png'
4995Binary files data/tmpicons/blogtk.png 1970-01-01 00:00:00 +0000 and data/tmpicons/blogtk.png 2014-03-08 03:45:16 +0000 differ
4996=== added file 'data/tmpicons/bluefish.png'
4997Binary files data/tmpicons/bluefish.png 1970-01-01 00:00:00 +0000 and data/tmpicons/bluefish.png 2014-03-08 03:45:16 +0000 differ
4998=== added file 'data/tmpicons/blueman.png'
4999Binary files data/tmpicons/blueman.png 1970-01-01 00:00:00 +0000 and data/tmpicons/blueman.png 2014-03-08 03:45:16 +0000 differ
5000=== added file 'data/tmpicons/bluemindo.png'
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: