[sulfur] migrate the whole application to the use of the new Entropy Web Services interface
This commit is contained in:
@@ -38,6 +38,7 @@ install:
|
||||
install -m755 $(MISCDIR)/sulfur-uri-handler $(DESTDIR)$(BINDIR)/.
|
||||
install -m644 $(MISCDIR)/entropy-handler.schemas $(DESTDIR)/etc/gconf/schemas/.
|
||||
install -m644 $(PIXDIR)/*.png $(DESTDIR)/usr/share/pixmaps/sulfur/.
|
||||
install -m644 $(PIXDIR)/*.gif $(DESTDIR)/usr/share/pixmaps/sulfur/.
|
||||
install -m644 $(PIXDIR)/packages/*.png $(DESTDIR)/usr/share/pixmaps/sulfur/packages/.
|
||||
install -m644 $(PIXDIR)/ugc/*.png $(DESTDIR)/usr/share/pixmaps/sulfur/ugc/.
|
||||
install -m644 $(MISCDIR)/kde_x-sulfur.desktop $(DESTDIR)/usr/share/mimelnk/application/.
|
||||
|
||||
+136
-79
@@ -43,13 +43,14 @@ from entropy.services.exceptions import EntropyServicesError
|
||||
import entropy.tools
|
||||
from entropy.const import etpConst, const_get_stringtype, \
|
||||
initconfig_entropy_constants, const_convert_to_unicode, \
|
||||
const_drop_privileges, const_regain_privileges
|
||||
const_debug_write
|
||||
from entropy.i18n import _
|
||||
from entropy.misc import ParallelTask
|
||||
from entropy.cache import EntropyCacher, MtimePingus
|
||||
from entropy.output import print_generic
|
||||
from entropy.db.exceptions import ProgrammingError, OperationalError
|
||||
from entropy.core.settings.base import SystemSettings
|
||||
from entropy.services.client import WebService
|
||||
|
||||
# Sulfur Imports
|
||||
import gtk, gobject
|
||||
@@ -59,7 +60,7 @@ from sulfur.setup import SulfurConf, const, fakeoutfile, fakeinfile, \
|
||||
cleanMarkupString
|
||||
from sulfur.widgets import SulfurConsole
|
||||
from sulfur.core import UI, Controller, FORK_PIDS, fork_function, \
|
||||
busy_cursor, normal_cursor
|
||||
busy_cursor, normal_cursor, get_entropy_webservice, Privileges
|
||||
from sulfur.views import *
|
||||
from sulfur.filters import Filter
|
||||
from sulfur.dialogs import *
|
||||
@@ -67,59 +68,14 @@ from sulfur.progress import Base as BaseProgress
|
||||
from sulfur.events import SulfurApplicationEventsMixin
|
||||
from sulfur.event import SulfurSignals
|
||||
|
||||
|
||||
class SulfurApplication(Controller, SulfurApplicationEventsMixin):
|
||||
|
||||
class Privileges:
|
||||
|
||||
def __init__(self, drop_privs = True):
|
||||
self.__drop_privs = drop_privs
|
||||
self.__drop_privs_lock = threading.RLock()
|
||||
self.__with_stmt = 0
|
||||
|
||||
def __enter__(self):
|
||||
"""
|
||||
Hold the lock.
|
||||
"""
|
||||
self.__drop_privs_lock.acquire()
|
||||
if self.__with_stmt < 1:
|
||||
self.regain()
|
||||
self.__with_stmt += 1
|
||||
|
||||
def __exit__(self, exc_type, exc_value, traceback):
|
||||
"""
|
||||
Drop the lock.
|
||||
"""
|
||||
if self.__with_stmt == 1:
|
||||
self.drop()
|
||||
self.__with_stmt -= 1
|
||||
self.__drop_privs_lock.release()
|
||||
|
||||
def drop(self):
|
||||
"""
|
||||
Drop process privileges. Setting unpriv_gid to etpConst['entropygid']
|
||||
makes Entropy UGC/Data cache handling working.
|
||||
"""
|
||||
if self.__drop_privs:
|
||||
with self.__drop_privs_lock:
|
||||
const_drop_privileges(unpriv_gid = etpConst['entropygid'])
|
||||
const.setup()
|
||||
|
||||
def regain(self):
|
||||
"""
|
||||
Regain previously dropped process privileges.
|
||||
"""
|
||||
if self.__drop_privs:
|
||||
with self.__drop_privs_lock:
|
||||
const_regain_privileges()
|
||||
const.setup()
|
||||
|
||||
def __init__(self, drop_privs = True):
|
||||
def __init__(self):
|
||||
|
||||
self.do_debug = False
|
||||
self._ugc_status = "--nougc" not in sys.argv
|
||||
|
||||
self._privileges = self.Privileges(drop_privs = drop_privs)
|
||||
self._privileges = Privileges()
|
||||
# Use this lock when you want to make sure that no other asynchronous
|
||||
# executions are being run.
|
||||
self._async_event_execution_lock = threading.Lock()
|
||||
@@ -127,6 +83,7 @@ class SulfurApplication(Controller, SulfurApplicationEventsMixin):
|
||||
self._entropy = Equo()
|
||||
self._cacher = EntropyCacher()
|
||||
self._settings = SystemSettings()
|
||||
self._webserv_map = {}
|
||||
|
||||
# support for packages installation on startup
|
||||
packages_install, atoms_install, do_fetch = \
|
||||
@@ -187,6 +144,40 @@ class SulfurApplication(Controller, SulfurApplicationEventsMixin):
|
||||
# init the Controller Class to connect signals.
|
||||
Controller.__init__( self, ui )
|
||||
|
||||
def _get_webservice(self, repository_id):
|
||||
webserv = self._webserv_map.get(repository_id)
|
||||
if webserv == -1:
|
||||
# not available
|
||||
return None
|
||||
if webserv is not None:
|
||||
return webserv
|
||||
|
||||
with self._privileges:
|
||||
# so that the correct auth store file is fetched
|
||||
# NOTE: other areas don't do the same, be careful
|
||||
try:
|
||||
webserv = get_entropy_webservice(self._entropy, repository_id)
|
||||
except WebService.UnsupportedService as err:
|
||||
webserv = None
|
||||
|
||||
if webserv is None:
|
||||
self._webserv_map[repository_id] = -1
|
||||
# not available
|
||||
return
|
||||
|
||||
try:
|
||||
available = webserv.service_available()
|
||||
except WebService.WebServiceException:
|
||||
available = False
|
||||
|
||||
if not available:
|
||||
self._webserv_map[repository_id] = -1
|
||||
# not available
|
||||
return
|
||||
|
||||
self._webserv_map[repository_id] = webserv
|
||||
return webserv
|
||||
|
||||
def __scan_packages_install(self):
|
||||
packages_install = os.environ.get("SULFUR_PACKAGES", '').split(";")
|
||||
atoms_install = []
|
||||
@@ -896,23 +887,38 @@ class SulfurApplication(Controller, SulfurApplicationEventsMixin):
|
||||
if self.do_debug:
|
||||
print_generic("entering UGC")
|
||||
|
||||
if self._entropy.UGC is None:
|
||||
return
|
||||
|
||||
if self._spawning_ugc or self.disable_ugc:
|
||||
return
|
||||
|
||||
if not force:
|
||||
eapi3_repos = []
|
||||
webserv_repos = []
|
||||
for repoid in self._entropy.repositories():
|
||||
aware = self._entropy.UGC.is_repository_eapi3_aware(repoid)
|
||||
webserv = self._get_webservice(repoid)
|
||||
if webserv is None:
|
||||
continue
|
||||
try:
|
||||
aware = webserv.service_available()
|
||||
except WebService.WebServiceException:
|
||||
continue
|
||||
if aware:
|
||||
eapi3_repos.append(repoid)
|
||||
webserv_repos.append((webserv, repoid))
|
||||
|
||||
cache_available = True
|
||||
for repoid in eapi3_repos:
|
||||
if not self._entropy.is_ugc_cached(repoid):
|
||||
for webserv, repoid in webserv_repos:
|
||||
cache_available = True
|
||||
try:
|
||||
webserv.get_available_votes(cache = True, cached = True)
|
||||
except WebService.CacheMiss:
|
||||
cache_available = False
|
||||
if cache_available:
|
||||
# also check downloads
|
||||
try:
|
||||
webserv.get_available_downloads(cache = True,
|
||||
cached = True)
|
||||
except WebService.CacheMiss:
|
||||
cache_available = False
|
||||
if not cache_available:
|
||||
break
|
||||
|
||||
pingus_id = "sulfur_ugc_content_spawn"
|
||||
# check if at least 2 hours are passed since last check
|
||||
@@ -936,9 +942,11 @@ class SulfurApplication(Controller, SulfurApplicationEventsMixin):
|
||||
self._ugc_update()
|
||||
self._cacher.sync()
|
||||
print_generic("UGC child process done")
|
||||
emit_ugc_update()
|
||||
|
||||
self._spawning_ugc = True
|
||||
fork_function(do_ugc_sync, emit_ugc_update)
|
||||
th = ParallelTask(do_ugc_sync)
|
||||
th.start()
|
||||
|
||||
if self.do_debug:
|
||||
print_generic("quitting UGC")
|
||||
@@ -947,15 +955,46 @@ class SulfurApplication(Controller, SulfurApplicationEventsMixin):
|
||||
|
||||
def _ugc_update(self):
|
||||
|
||||
def _update_available_cache(repository_id):
|
||||
webserv = self._get_webservice(repository_id)
|
||||
if webserv is None:
|
||||
return
|
||||
|
||||
# fetch vote cache first
|
||||
try:
|
||||
webserv.get_available_votes(cache = False)
|
||||
except WebService.WebServiceException as err:
|
||||
const_debug_write(__name__,
|
||||
"_ugc_update.get_available_votes: ouch %s" % (err,))
|
||||
return
|
||||
# drop get_votes cache completely
|
||||
# this enforces EntropyPackage.vote* to use available_votes cache
|
||||
webserv._drop_cached("get_votes")
|
||||
|
||||
try:
|
||||
webserv.get_available_downloads(cache = False)
|
||||
except WebService.WebServiceException as err:
|
||||
const_debug_write(__name__,
|
||||
"_ugc_update.get_available_downloads: ouch %s" % (err,))
|
||||
return
|
||||
# drop get_downloads cache completely
|
||||
# this enforces EntropyPackage.down* to use available_downloads
|
||||
# cache
|
||||
webserv._drop_cached("get_downloads")
|
||||
|
||||
|
||||
for repo in self._entropy.repositories():
|
||||
if self.do_debug:
|
||||
t1 = time.time()
|
||||
print_generic("working UGC update for", repo)
|
||||
self._entropy.update_ugc_cache(repo)
|
||||
if self.do_debug:
|
||||
t2 = time.time()
|
||||
td = t2 - t1
|
||||
print_generic("completed UGC update for", repo, "took", td)
|
||||
t1 = time.time()
|
||||
const_debug_write(__name__,
|
||||
"working UGC update for %s" % (repo,))
|
||||
|
||||
_update_available_cache(repo)
|
||||
|
||||
t2 = time.time()
|
||||
td = t2 - t1
|
||||
const_debug_write(__name__,
|
||||
"completed UGC update for %s, took %s" % (
|
||||
repo, td,))
|
||||
|
||||
def fill_pref_db_backup_page(self):
|
||||
self.dbBackupStore.clear()
|
||||
@@ -1030,22 +1069,31 @@ class SulfurApplication(Controller, SulfurApplicationEventsMixin):
|
||||
obj = model.get_value( myiter, 0 )
|
||||
if obj:
|
||||
t = "<i>%s</i>" % (_("Not logged in"),)
|
||||
if self._entropy.UGC != None:
|
||||
logged_data = self._entropy.UGC.read_login(obj['repoid'])
|
||||
if logged_data != None:
|
||||
t = "<i>%s</i>" % (logged_data[0],)
|
||||
webserv = self._get_webservice(obj['repoid'])
|
||||
if webserv is None:
|
||||
t = "<i>%s</i>" % (_("Not available"),)
|
||||
else:
|
||||
with self._privileges:
|
||||
username = webserv.get_credentials()
|
||||
if username is not None:
|
||||
t = "<i>%s</i>" % (username,)
|
||||
cell.set_property('markup', t)
|
||||
|
||||
def get_ugc_status_pix( column, cell, model, myiter ):
|
||||
if self._entropy.UGC == None:
|
||||
cell.set_property('icon-name', 'gtk-cancel')
|
||||
return
|
||||
if not self._ugc_status:
|
||||
cell.set_property('icon-name', 'gtk-cancel')
|
||||
return
|
||||
obj = model.get_value( myiter, 0 )
|
||||
if obj:
|
||||
if self._entropy.UGC.is_repository_eapi3_aware(obj['repoid']):
|
||||
webserv = self._get_webservice(obj['repoid'])
|
||||
if webserv is None:
|
||||
cell.set_property( 'icon-name', 'gtk-cancel' )
|
||||
return
|
||||
try:
|
||||
available = webserv.service_available()
|
||||
except WebService.WebServiceException:
|
||||
available = False
|
||||
if available:
|
||||
cell.set_property( 'icon-name', 'gtk-apply' )
|
||||
else:
|
||||
cell.set_property( 'icon-name', 'gtk-cancel' )
|
||||
@@ -1436,11 +1484,20 @@ class SulfurApplication(Controller, SulfurApplicationEventsMixin):
|
||||
|
||||
for repo in repos:
|
||||
# inform UGC that we are syncing this repo
|
||||
if self._entropy.UGC is not None:
|
||||
try:
|
||||
self._entropy.UGC.add_download_stats(repo, [repo])
|
||||
except EntropyServicesError:
|
||||
continue
|
||||
webserv = self._get_webservice(repository)
|
||||
if webserv is None:
|
||||
continue
|
||||
try:
|
||||
available = webserv.service_available()
|
||||
except WebService.WebServiceException:
|
||||
continue
|
||||
if not available:
|
||||
continue
|
||||
try:
|
||||
webserv.add_downloads([repo])
|
||||
except WebService.WebServiceException as err:
|
||||
const_debug_write(__name__, repr(err))
|
||||
continue
|
||||
|
||||
if repoConn.sync_errors or (rc != 0):
|
||||
self.progress.set_mainLabel(_('Errors updating repositories.'))
|
||||
|
||||
@@ -19,12 +19,16 @@
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
import threading
|
||||
|
||||
import gtk
|
||||
import gtk.glade
|
||||
import gobject
|
||||
from entropy.const import const_debug_write
|
||||
from entropy.const import const_debug_write, const_drop_privileges, \
|
||||
const_regain_privileges, etpConst
|
||||
from entropy.misc import ParallelTask
|
||||
from entropy.core import Singleton
|
||||
from sulfur.setup import const
|
||||
|
||||
FORK_PIDS = []
|
||||
|
||||
@@ -164,6 +168,26 @@ def resize_image(max_width, image_path, new_image_path):
|
||||
del img_buf
|
||||
del img
|
||||
|
||||
def resize_image_height(max_height, image_path, new_image_path):
|
||||
shutil.copy2(image_path, new_image_path)
|
||||
img = gtk.Image()
|
||||
img.set_from_file(new_image_path)
|
||||
img_buf = img.get_pixbuf()
|
||||
w, h = img_buf.get_width(), img_buf.get_height()
|
||||
if h > max_height:
|
||||
# resize pix
|
||||
new_h = max_height
|
||||
new_w = new_h*w/h
|
||||
img_buf = img_buf.scale_simple(int(new_w),
|
||||
int(new_h), gtk.gdk.INTERP_BILINEAR)
|
||||
try:
|
||||
img_buf.save(new_image_path, "png")
|
||||
except gobject.GError:
|
||||
# libpng issue? try jpeg
|
||||
img_buf.save(new_image_path, "jpeg")
|
||||
del img_buf
|
||||
del img
|
||||
|
||||
def load_url(url):
|
||||
xdg_open = '/usr/bin/xdg-open'
|
||||
if os.access(xdg_open, os.X_OK):
|
||||
@@ -172,3 +196,66 @@ def load_url(url):
|
||||
# child
|
||||
os.execv(xdg_open, [xdg_open, url])
|
||||
os._exit(0)
|
||||
|
||||
def get_entropy_webservice(entropy_client, repository_id, tx_cb = None):
|
||||
"""
|
||||
Get Entropy Web Services service object (ClientWebService).
|
||||
|
||||
@param entropy_client: Entropy Client interface
|
||||
@type entropy_client: entropy.client.interfaces.Client
|
||||
@param repository_id: repository identifier
|
||||
@type repository_id: string
|
||||
@return: the ClientWebService instance
|
||||
@rtype: entropy.client.services.interfaces.ClientWebService
|
||||
@raise WebService.UnsupportedService: if service is unsupported by
|
||||
repository
|
||||
"""
|
||||
factory = entropy_client.WebServices()
|
||||
webserv = factory.new(repository_id)
|
||||
if tx_cb is not None:
|
||||
webserv._set_transfer_callback(tx_cb)
|
||||
return webserv
|
||||
|
||||
class Privileges(Singleton):
|
||||
|
||||
def init_singleton(self):
|
||||
self.__drop_privs = True
|
||||
self.__drop_privs_lock = threading.RLock()
|
||||
self.__with_stmt = 0
|
||||
|
||||
def __enter__(self):
|
||||
"""
|
||||
Hold the lock.
|
||||
"""
|
||||
self.__drop_privs_lock.acquire()
|
||||
if self.__with_stmt < 1:
|
||||
self.regain()
|
||||
self.__with_stmt += 1
|
||||
|
||||
def __exit__(self, exc_type, exc_value, traceback):
|
||||
"""
|
||||
Drop the lock.
|
||||
"""
|
||||
if self.__with_stmt == 1:
|
||||
self.drop()
|
||||
self.__with_stmt -= 1
|
||||
self.__drop_privs_lock.release()
|
||||
|
||||
def drop(self):
|
||||
"""
|
||||
Drop process privileges. Setting unpriv_gid to etpConst['entropygid']
|
||||
makes Entropy UGC/Data cache handling working.
|
||||
"""
|
||||
if self.__drop_privs:
|
||||
with self.__drop_privs_lock:
|
||||
const_drop_privileges(unpriv_gid = etpConst['entropygid'])
|
||||
const.setup()
|
||||
|
||||
def regain(self):
|
||||
"""
|
||||
Regain previously dropped process privileges.
|
||||
"""
|
||||
if self.__drop_privs:
|
||||
with self.__drop_privs_lock:
|
||||
const_regain_privileges()
|
||||
const.setup()
|
||||
|
||||
+590
-349
File diff suppressed because it is too large
Load Diff
@@ -25,10 +25,11 @@ except ImportError:
|
||||
import _thread as thread
|
||||
from sulfur.setup import const, SulfurConf
|
||||
from sulfur.dialogs import LicenseDialog, okDialog, choiceDialog, inputDialog
|
||||
from sulfur.core import get_entropy_webservice
|
||||
import gobject
|
||||
|
||||
# Entropy Imports
|
||||
from entropy.const import etpConst, etpUi
|
||||
from entropy.const import etpConst, etpUi, const_debug_write
|
||||
from entropy.output import print_generic, nocolor, decolorize
|
||||
from entropy.client.interfaces import Client
|
||||
from entropy.fetchers import UrlFetcher
|
||||
@@ -37,6 +38,7 @@ from entropy.misc import ParallelTask
|
||||
from entropy.client.mirrors import StatusInterface
|
||||
from entropy.exceptions import RepositoryError
|
||||
from entropy.db.exceptions import OperationalError, IntegrityError
|
||||
from entropy.services.client import WebService
|
||||
|
||||
import entropy.dep
|
||||
import entropy.tools
|
||||
@@ -193,14 +195,22 @@ class QueueExecutor:
|
||||
|
||||
if not download_sources:
|
||||
def spawn_ugc():
|
||||
try:
|
||||
if self._entropy.UGC != None:
|
||||
for myrepo in mykeys:
|
||||
mypkgkeys = sorted(mykeys[myrepo])
|
||||
self._entropy.UGC.add_download_stats(myrepo,
|
||||
mypkgkeys)
|
||||
except:
|
||||
pass
|
||||
for myrepo, mykeys in mykeys.items():
|
||||
try:
|
||||
webserv = get_entropy_webservice(self._entropy,
|
||||
myrepo)
|
||||
except WebService.UnsupportedService:
|
||||
continue
|
||||
try:
|
||||
avail = webserv.service_available()
|
||||
except WebService.WebServiceException:
|
||||
avail = False
|
||||
if avail:
|
||||
try:
|
||||
webserv.add_downloads(sorted(mykeys))
|
||||
except WebService.WebServiceException as err:
|
||||
const_debug_write(__name__, repr(err))
|
||||
continue
|
||||
spawn_ugc()
|
||||
|
||||
def do_skip_hide():
|
||||
@@ -315,8 +325,6 @@ class Equo(Client):
|
||||
Client.init_singleton(self, *args, **kwargs)
|
||||
self._progress_divider = 1
|
||||
self.xcache = True # force xcache enabling
|
||||
if etpUi['debug']:
|
||||
self.UGC.quiet = False
|
||||
self._mthread_rc = {
|
||||
'ask_question': {},
|
||||
'input_box': {},
|
||||
|
||||
+51
-23
@@ -35,6 +35,7 @@ from entropy.output import print_generic
|
||||
from entropy.i18n import _
|
||||
from entropy.misc import ParallelTask
|
||||
from entropy.client.mirrors import StatusInterface
|
||||
from entropy.services.client import WebService
|
||||
import entropy.dump
|
||||
|
||||
from sulfur.filters import Filter
|
||||
@@ -563,7 +564,8 @@ class SulfurApplicationEventsMixin:
|
||||
|
||||
do_clear_filter_bar = False
|
||||
if action != self.lastPkgPB:
|
||||
do_clear_filter_bar = True
|
||||
# disabled for now, users are complaining
|
||||
do_clear_filter_bar = False
|
||||
|
||||
if action == "updates":
|
||||
self.ui.updatesButtonbox.show()
|
||||
@@ -813,46 +815,72 @@ class SulfurApplicationEventsMixin:
|
||||
self.load_color_settings()
|
||||
|
||||
def on_ugcLoginButton_clicked(self, widget):
|
||||
if self._entropy.UGC == None: return
|
||||
if not self._ugc_status:
|
||||
return
|
||||
model, myiter = self.ugcRepositoriesView.get_selection().get_selected()
|
||||
if (myiter == None) or (model == None): return
|
||||
if (myiter == None) or (model == None):
|
||||
return
|
||||
obj = model.get_value( myiter, 0 )
|
||||
if obj:
|
||||
#logged_data = self._entropy.UGC.read_login(obj['repoid'])
|
||||
self._entropy.UGC.login(obj['repoid'], force = True)
|
||||
webserv = self._get_webservice(obj['repoid'])
|
||||
if webserv is None:
|
||||
return
|
||||
|
||||
def fake_callback(*args, **kwargs):
|
||||
return True
|
||||
|
||||
# use input box to read login
|
||||
input_params = [
|
||||
('username', _('Username'), fake_callback, False),
|
||||
('password', _('Password'), fake_callback, True)
|
||||
]
|
||||
login_data = self._entropy.input_box(
|
||||
"%s %s %s" % (
|
||||
_('Please login against'), obj['repoid'], _('repository'),),
|
||||
input_params,
|
||||
cancel_button = True
|
||||
)
|
||||
if not login_data:
|
||||
okDialog(self.ui.main, _("Login aborted. Not logged in."))
|
||||
return
|
||||
|
||||
username, password = login_data['username'], login_data['password']
|
||||
with self._privileges:
|
||||
webserv.add_credentials(username, password)
|
||||
try:
|
||||
webserv.validate_credentials()
|
||||
except WebService.AuthenticationFailed:
|
||||
okDialog(self.ui.main,
|
||||
_("Authentication error. Not logged in."))
|
||||
return
|
||||
self.load_ugc_repositories()
|
||||
|
||||
def on_ugcClearLoginButton_clicked(self, widget):
|
||||
if self._entropy.UGC == None: return
|
||||
if not self._ugc_status:
|
||||
return
|
||||
model, myiter = self.ugcRepositoriesView.get_selection().get_selected()
|
||||
if (myiter == None) or (model == None): return
|
||||
if (myiter == None) or (model == None):
|
||||
return
|
||||
obj = model.get_value( myiter, 0 )
|
||||
if obj:
|
||||
if not self._entropy.UGC.is_repository_eapi3_aware(obj['repoid']):
|
||||
webserv = self._get_webservice(obj['repoid'])
|
||||
if webserv is None:
|
||||
return
|
||||
logged_data = self._entropy.UGC.read_login(obj['repoid'])
|
||||
if logged_data: self._entropy.UGC.remove_login(obj['repoid'])
|
||||
with self._privileges:
|
||||
webserv.remove_credentials()
|
||||
self.load_ugc_repositories()
|
||||
|
||||
def on_ugcClearCacheButton_clicked(self, widget):
|
||||
if self._entropy.UGC == None: return
|
||||
repo_excluded = self._settings['repositories']['excluded']
|
||||
avail_repos = self._settings['repositories']['available']
|
||||
for repoid in list(set(list(avail_repos.keys())+list(repo_excluded.keys()))):
|
||||
self._entropy.UGC.UGCCache.clear_cache(repoid)
|
||||
self.set_status_ticker("%s: %s ..." % (_("Cleaning UGC cache of"), repoid,))
|
||||
self.set_status_ticker("%s" % (_("UGC cache cleared"),))
|
||||
|
||||
def on_ugcClearCredentialsButton_clicked(self, widget):
|
||||
if self._entropy.UGC == None:
|
||||
if not self._ugc_status:
|
||||
return
|
||||
repo_excluded = self._settings['repositories']['excluded']
|
||||
avail_repos = self._settings['repositories']['available']
|
||||
for repoid in list(set(list(avail_repos.keys())+list(repo_excluded.keys()))):
|
||||
if not self._entropy.UGC.is_repository_eapi3_aware(repoid):
|
||||
webserv = self._get_webservice(repoid)
|
||||
if webserv is None:
|
||||
continue
|
||||
logged_data = self._entropy.UGC.read_login(repoid)
|
||||
if logged_data: self._entropy.UGC.remove_login(repoid)
|
||||
with self._privileges:
|
||||
webserv.remove_credentials()
|
||||
self.load_ugc_repositories()
|
||||
self.set_status_ticker("%s" % (_("UGC credentials cleared"),))
|
||||
|
||||
|
||||
@@ -14,10 +14,15 @@ from entropy.const import *
|
||||
from entropy.i18n import _
|
||||
import entropy.dep
|
||||
import entropy.tools
|
||||
from entropy.services.client import WebService
|
||||
|
||||
from sulfur.entropyapi import Equo
|
||||
from sulfur.setup import cleanMarkupString, SulfurConf
|
||||
from sulfur.core import get_entropy_webservice
|
||||
|
||||
|
||||
ENTROPY = Equo()
|
||||
WEBSERV_MAP = {}
|
||||
|
||||
class DummyEntropyPackage:
|
||||
|
||||
@@ -130,6 +135,25 @@ class EntropyPackage:
|
||||
self.matched_atom = matched_atom
|
||||
self.installed_match = None
|
||||
|
||||
def _get_webservice(self):
|
||||
|
||||
repository_id = self.get_repository_clean()
|
||||
webserv = WEBSERV_MAP.get(repository_id)
|
||||
|
||||
if webserv == -1:
|
||||
return None # not available
|
||||
if webserv is not None:
|
||||
return webserv
|
||||
|
||||
try:
|
||||
webserv = get_entropy_webservice(ENTROPY, repository_id)
|
||||
except WebService.UnsupportedService:
|
||||
WEBSERV_MAP[repository_id] = -1
|
||||
return None
|
||||
|
||||
WEBSERV_MAP[repository_id] = webserv
|
||||
return webserv
|
||||
|
||||
# for debugging purposes, sample method
|
||||
"""
|
||||
def __setattr__(self, name, value):
|
||||
@@ -263,8 +287,7 @@ class EntropyPackage:
|
||||
if atom is None: # wtf!
|
||||
return 'N/A'
|
||||
|
||||
key = entropy.dep.dep_getkey(atom)
|
||||
downloads = ENTROPY.UGC.UGCCache.get_package_downloads(repo_clean, key)
|
||||
downloads = self.get_ugc_package_downloads()
|
||||
ugc_string = '<small>[%s|<span foreground="%s">%s</span>]</small> ' % (
|
||||
downloads, SulfurConf.color_title2, repo_clean,)
|
||||
if ver_str:
|
||||
@@ -577,14 +600,40 @@ class EntropyPackage:
|
||||
return ENTROPY.Settings()['repositories']['branch']
|
||||
return self.dbconn.retrieveBranch(self.matched_id)
|
||||
|
||||
def _get_vote_raw(self, pkg_key):
|
||||
webserv = self._get_webservice()
|
||||
if webserv is None:
|
||||
return None
|
||||
|
||||
# try to get vote for the single package first, if it fails,
|
||||
# we'll search the info inside the available vote data.
|
||||
got_miss = False
|
||||
try:
|
||||
vote = webserv.get_votes([pkg_key], cache = True,
|
||||
cached = True)[pkg_key]
|
||||
except WebService.CacheMiss:
|
||||
vote = None
|
||||
got_miss = True
|
||||
|
||||
# found it?
|
||||
if vote is not None:
|
||||
return vote
|
||||
|
||||
# fallback to available cache
|
||||
try:
|
||||
return webserv.get_available_votes(cache = True,
|
||||
cached = True).get(pkg_key)
|
||||
except WebService.CacheMiss:
|
||||
return None
|
||||
|
||||
def get_ugc_package_vote(self):
|
||||
if self.pkgset:
|
||||
return -1
|
||||
atom = self.get_name()
|
||||
if not atom:
|
||||
return None
|
||||
return ENTROPY.UGC.UGCCache.get_package_vote(
|
||||
self.get_repository_clean(), entropy.dep.dep_getkey(atom))
|
||||
pkg_key = entropy.dep.dep_getkey(atom)
|
||||
return self._get_vote_raw(pkg_key)
|
||||
|
||||
def get_ugc_package_vote_int(self):
|
||||
if self.pkgset:
|
||||
@@ -592,9 +641,10 @@ class EntropyPackage:
|
||||
atom = self.get_name()
|
||||
if not atom:
|
||||
return 0
|
||||
vote = ENTROPY.UGC.UGCCache.get_package_vote(
|
||||
self.get_repository_clean(), entropy.dep.dep_getkey(atom))
|
||||
if not isinstance(vote, float):
|
||||
|
||||
pkg_key = entropy.dep.dep_getkey(atom)
|
||||
vote = self._get_vote_raw(pkg_key)
|
||||
if vote is None:
|
||||
return 0
|
||||
return int(vote)
|
||||
|
||||
@@ -604,9 +654,10 @@ class EntropyPackage:
|
||||
atom = self.get_name()
|
||||
if not atom:
|
||||
return 0.0
|
||||
vote = ENTROPY.UGC.UGCCache.get_package_vote(
|
||||
self.get_repository_clean(), entropy.dep.dep_getkey(atom))
|
||||
if not isinstance(vote, float):
|
||||
|
||||
pkg_key = entropy.dep.dep_getkey(atom)
|
||||
vote = self._get_vote_raw(pkg_key)
|
||||
if vote is None:
|
||||
return 0.0
|
||||
return vote
|
||||
|
||||
@@ -619,9 +670,17 @@ class EntropyPackage:
|
||||
atom = self.get_name()
|
||||
if not atom:
|
||||
return 0
|
||||
key = entropy.dep.dep_getkey(atom)
|
||||
return ENTROPY.UGC.UGCCache.get_package_downloads(
|
||||
self.get_repository_clean(), key)
|
||||
|
||||
webserv = self._get_webservice()
|
||||
if webserv is None:
|
||||
return 0
|
||||
pkg_key = entropy.dep.dep_getkey(atom)
|
||||
try:
|
||||
downloads = webserv.get_available_downloads(cache = True,
|
||||
cached = True).get(pkg_key, 0)
|
||||
except WebService.CacheMiss:
|
||||
return 0
|
||||
return downloads
|
||||
|
||||
def get_attribute(self, attr):
|
||||
cached = self.__cache.get(('get_attribute', attr,))
|
||||
|
||||
+39
-152
@@ -124,9 +124,9 @@
|
||||
<property name="can_focus">True</property>
|
||||
<property name="border_width">2</property>
|
||||
<property name="show_border">False</property>
|
||||
<signal name="change_current_page" handler="on_notebook_change_current_page"/>
|
||||
<signal name="switch_page" handler="on_notebook_switch_page"/>
|
||||
<signal name="select_page" handler="on_notebook_select_page"/>
|
||||
<signal name="change_current_page" handler="on_notebook_change_current_page"/>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="packagesVbox">
|
||||
<property name="visible">True</property>
|
||||
@@ -2740,8 +2740,8 @@ Relaxed</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<signal name="clicked" handler="on_configProtectSkipNew_clicked"/>
|
||||
<signal name="released" handler="on_Preferences_toggled"/>
|
||||
<signal name="clicked" handler="on_configProtectSkipNew_clicked"/>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image23">
|
||||
<property name="visible">True</property>
|
||||
@@ -2783,8 +2783,8 @@ Relaxed</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<signal name="clicked" handler="on_configProtectSkipDelete_clicked"/>
|
||||
<signal name="released" handler="on_Preferences_toggled"/>
|
||||
<signal name="clicked" handler="on_configProtectSkipDelete_clicked"/>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image36">
|
||||
<property name="visible">True</property>
|
||||
@@ -2869,8 +2869,8 @@ Relaxed</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<signal name="clicked" handler="on_configProtectMaskNew_clicked"/>
|
||||
<signal name="released" handler="on_Preferences_toggled"/>
|
||||
<signal name="clicked" handler="on_configProtectMaskNew_clicked"/>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image15">
|
||||
<property name="visible">True</property>
|
||||
@@ -2891,8 +2891,8 @@ Relaxed</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<signal name="clicked" handler="on_configProtectMaskEdit_clicked"/>
|
||||
<signal name="released" handler="on_Preferences_toggled"/>
|
||||
<signal name="clicked" handler="on_configProtectMaskEdit_clicked"/>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image29">
|
||||
<property name="visible">True</property>
|
||||
@@ -2913,8 +2913,8 @@ Relaxed</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<signal name="clicked" handler="on_configProtectMaskDelete_clicked"/>
|
||||
<signal name="released" handler="on_Preferences_toggled"/>
|
||||
<signal name="clicked" handler="on_configProtectMaskDelete_clicked"/>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image35">
|
||||
<property name="visible">True</property>
|
||||
@@ -2998,8 +2998,8 @@ Relaxed</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<signal name="clicked" handler="on_configProtectNew_clicked"/>
|
||||
<signal name="released" handler="on_Preferences_toggled"/>
|
||||
<signal name="clicked" handler="on_configProtectNew_clicked"/>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image13">
|
||||
<property name="visible">True</property>
|
||||
@@ -3020,8 +3020,8 @@ Relaxed</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<signal name="clicked" handler="on_configProtectEdit_clicked"/>
|
||||
<signal name="released" handler="on_Preferences_toggled"/>
|
||||
<signal name="clicked" handler="on_configProtectEdit_clicked"/>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image27">
|
||||
<property name="visible">True</property>
|
||||
@@ -3042,8 +3042,8 @@ Relaxed</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<signal name="clicked" handler="on_configProtectDelete_clicked"/>
|
||||
<signal name="released" handler="on_Preferences_toggled"/>
|
||||
<signal name="clicked" handler="on_configProtectDelete_clicked"/>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image33">
|
||||
<property name="visible">True</property>
|
||||
@@ -3441,34 +3441,6 @@ Relaxed</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="ugcClearCacheButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip" translatable="yes">Clear all cache</property>
|
||||
<signal name="clicked" handler="on_ugcClearCacheButton_clicked"/>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox46">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image37">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-harddisk</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
@@ -6998,8 +6970,8 @@ gz</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="on_closeInfo_clicked"/>
|
||||
<signal name="delete_event" handler="on_closeInfo_delete_event"/>
|
||||
<signal name="clicked" handler="on_closeInfo_clicked"/>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image14">
|
||||
<property name="visible">True</property>
|
||||
@@ -7988,90 +7960,6 @@ gz</property>
|
||||
<widget class="GtkVBox" id="vbox53">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox32">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="ugcIcon">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-dnd</property>
|
||||
<property name="pixel_size">0</property>
|
||||
<property name="icon-size">6</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">3</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox60">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="ugcTitleLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">1</property>
|
||||
<property name="label" translatable="yes">User Generated Content</property>
|
||||
<property name="use_markup">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="padding">3</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="ugcDescriptionLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0</property>
|
||||
<property name="label">User Generated Content description</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment10">
|
||||
<property name="visible">True</property>
|
||||
<property name="bottom_padding">20</property>
|
||||
<property name="right_padding">6</property>
|
||||
<child>
|
||||
<widget class="GtkButton" id="loadUgcButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip" translatable="yes">Load User Generated Content</property>
|
||||
<signal name="clicked" handler="on_loadUgcButton_clicked"/>
|
||||
<child>
|
||||
<widget class="GtkImage" id="refreshImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-refresh</property>
|
||||
<property name="icon-size">6</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="padding">6</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox55">
|
||||
<property name="visible">True</property>
|
||||
@@ -8195,7 +8083,6 @@ gz</property>
|
||||
<child>
|
||||
<widget class="GtkHButtonBox" id="hbuttonbox5">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">6</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<widget class="GtkButton" id="ugcShowButton">
|
||||
@@ -8238,6 +8125,29 @@ gz</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="loadUgcButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="has_tooltip">True</property>
|
||||
<property name="tooltip" translatable="yes">Load User Generated Content</property>
|
||||
<signal name="clicked" handler="on_loadUgcButton_clicked"/>
|
||||
<child>
|
||||
<widget class="GtkImage" id="refreshImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="pixel_size">22</property>
|
||||
<property name="icon_name">view-refresh</property>
|
||||
<property name="icon-size">3</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
@@ -8247,7 +8157,7 @@ gz</property>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
@@ -9282,6 +9192,7 @@ Please read them carefully and <b>make your choice</b>.</property>
|
||||
<widget class="GtkVBox" id="vbox59">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox3">
|
||||
<property name="visible">True</property>
|
||||
@@ -9359,8 +9270,8 @@ Please read them carefully and <b>make your choice</b>.</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="on_closeInfo_clicked"/>
|
||||
<signal name="delete_event" handler="on_closeInfo_clicked"/>
|
||||
<signal name="clicked" handler="on_closeInfo_clicked"/>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image20">
|
||||
<property name="visible">True</property>
|
||||
@@ -9385,37 +9296,13 @@ Please read them carefully and <b>make your choice</b>.</property>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox64">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<widget class="GtkTable" id="ugcTable">
|
||||
<property name="visible">True</property>
|
||||
<property name="n_rows">6</property>
|
||||
<property name="n_rows">5</property>
|
||||
<property name="n_columns">2</property>
|
||||
<property name="row_spacing">3</property>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="sizeContent">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label">this is the size</property>
|
||||
<property name="wrap">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">5</property>
|
||||
<property name="bottom_attach">6</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="sizeLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Size</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">5</property>
|
||||
<property name="bottom_attach">6</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="keywordsContent">
|
||||
<property name="visible">True</property>
|
||||
@@ -11393,8 +11280,8 @@ Please read them carefully and <b>make your choice</b>.</property>
|
||||
<child>
|
||||
<widget class="GtkEventBox" id="repoManagerConsoleEvent">
|
||||
<property name="visible">True</property>
|
||||
<signal name="enter_notify_event" handler="on_repoManagerConsoleEvent_enter_notify_event"/>
|
||||
<signal name="key_release_event" handler="on_repoManagerConsoleEvent_key_release_event"/>
|
||||
<signal name="enter_notify_event" handler="on_repoManagerConsoleEvent_enter_notify_event"/>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="repoManagerTermHBox">
|
||||
<property name="visible">True</property>
|
||||
|
||||
+292
-125
@@ -25,16 +25,16 @@ import tempfile
|
||||
|
||||
from entropy.exceptions import RepositoryError, InvalidPackageSet
|
||||
from entropy.const import etpConst, etpSys, initconfig_entropy_constants, \
|
||||
const_debug_write
|
||||
const_debug_write, const_debug_enabled, const_get_stringtype
|
||||
from entropy.misc import ParallelTask, TimeScheduled
|
||||
from entropy.i18n import _, _LOCALE
|
||||
from entropy.tools import print_traceback
|
||||
from entropy.dep import dep_getkey
|
||||
from entropy.const import const_get_stringtype
|
||||
|
||||
from sulfur.setup import const, cleanMarkupString, SulfurConf
|
||||
from sulfur.core import UI, busy_cursor, normal_cursor, \
|
||||
STATUS_BAR_CONTEXT_IDS, resize_image, fork_function
|
||||
STATUS_BAR_CONTEXT_IDS, resize_image, fork_function, \
|
||||
get_entropy_webservice, Privileges
|
||||
from sulfur.widgets import CellRendererStars
|
||||
from sulfur.package import DummyEntropyPackage, EntropyPackage
|
||||
from sulfur.entropyapi import Equo
|
||||
@@ -44,6 +44,8 @@ from sulfur.event import SulfurSignals
|
||||
|
||||
from entropy.db.exceptions import ProgrammingError, Error as DbError, \
|
||||
OperationalError, DatabaseError
|
||||
from entropy.services.client import WebService
|
||||
from entropy.client.services.interfaces import ClientWebService
|
||||
|
||||
class EntropyPackageViewModelInjector:
|
||||
|
||||
@@ -494,6 +496,7 @@ class EntropyPackageView:
|
||||
self.selected_objs = []
|
||||
self.last_row = None
|
||||
self.loaded_reinstallables = []
|
||||
self._webserv_map = {}
|
||||
self._pixbuf_map = {}
|
||||
self.loaded_event = None
|
||||
self.do_refresh_view = False
|
||||
@@ -689,15 +692,14 @@ class EntropyPackageView:
|
||||
self.queue_full_exception = Full
|
||||
self.queue_empty_exception = Empty
|
||||
|
||||
self.__pkg_ugc_icon_local_path_cache = {}
|
||||
self.__pkg_ugc_icon_cache = {}
|
||||
self.__pkg_ugc_icon_call_cache = {}
|
||||
# max 64 items at time, don't lower it too much, can cause
|
||||
# request starvation with the current very low priority
|
||||
self._ugc_load_queue = queue_class(64)
|
||||
self._ugc_load_thread = TimeScheduled(3, self._ugc_queue_run)
|
||||
# avoid DoS, lol
|
||||
self._ugc_icon_load_queue = queue_class(64)
|
||||
self._ugc_icon_thread = TimeScheduled(3, self._ugc_icon_queue_run)
|
||||
if self._ugc_status:
|
||||
# deferred loading, speedup UI init
|
||||
gobject.timeout_add_seconds(15, self._ugc_load_thread.start)
|
||||
gobject.timeout_add_seconds(15, self._ugc_icon_thread.start)
|
||||
|
||||
def __update_ugc_event(self, event):
|
||||
self.view.queue_draw()
|
||||
@@ -864,7 +866,7 @@ class EntropyPackageView:
|
||||
self.loaded_event = event
|
||||
del self.loaded_reinstallables[:]
|
||||
|
||||
if objs == None:
|
||||
if objs is None:
|
||||
objs = self.collect_selected_items(widget)
|
||||
|
||||
event_x = event.x
|
||||
@@ -909,16 +911,16 @@ class EntropyPackageView:
|
||||
|
||||
return True
|
||||
|
||||
elif len(objs) == 1:
|
||||
obj = objs[0]
|
||||
distance = 0
|
||||
for col in self.view.get_columns()[0:2]:
|
||||
distance += col.get_width()
|
||||
if (event_x > distance) and (event_x < (distance+self.stars_col_size)):
|
||||
vote = int((event_x - distance)/self.stars_col_size*5)+1
|
||||
# this is required to fix idiotic GTK behaviour
|
||||
elif column.get_title() == self.pkgcolumn_text_rating:
|
||||
def _do_vote(x, widget):
|
||||
rel_distance = x
|
||||
valid_votes = ClientWebService.VALID_VOTES
|
||||
vote = int(float(rel_distance) / self.stars_col_size * \
|
||||
len(valid_votes)) + 1
|
||||
self.delayed_vote_submit(widget, vote)
|
||||
return True
|
||||
return False
|
||||
gobject.idle_add(_do_vote, x, widget)
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
@@ -952,6 +954,7 @@ class EntropyPackageView:
|
||||
|
||||
def run_properties_menu(self, menu_item):
|
||||
objs = self.collect_selected_items()
|
||||
|
||||
for obj in objs:
|
||||
if obj.is_group or obj.is_pkgset_cat:
|
||||
continue
|
||||
@@ -1141,7 +1144,8 @@ class EntropyPackageView:
|
||||
busy_cursor(self.main_window)
|
||||
objs = self.selected_objs
|
||||
oldmask = self.etpbase.unmaskingPackages.copy()
|
||||
mydialog = MaskedPackagesDialog(self._entropy, self.etpbase, self.ui.main, objs)
|
||||
mydialog = MaskedPackagesDialog(self._entropy, self.etpbase,
|
||||
self.ui.main, objs)
|
||||
result = mydialog.run()
|
||||
if result != -5:
|
||||
self.etpbase.unmaskingPackages = oldmask.copy()
|
||||
@@ -1734,25 +1738,116 @@ class EntropyPackageView:
|
||||
|
||||
return store
|
||||
|
||||
def _get_webservice(self, repository_id):
|
||||
webserv = self._webserv_map.get(repository_id)
|
||||
if webserv == -1:
|
||||
# not available
|
||||
return None
|
||||
if webserv is not None:
|
||||
return webserv
|
||||
|
||||
with Privileges():
|
||||
try:
|
||||
webserv = get_entropy_webservice(self._entropy, repository_id)
|
||||
except WebService.UnsupportedService as err:
|
||||
webserv = None
|
||||
|
||||
if webserv is None:
|
||||
self._webserv_map[repository_id] = -1
|
||||
# not available
|
||||
return
|
||||
|
||||
try:
|
||||
available = webserv.service_available()
|
||||
except WebService.WebServiceException:
|
||||
available = False
|
||||
|
||||
if not available:
|
||||
self._webserv_map[repository_id] = -1
|
||||
# not available
|
||||
return
|
||||
|
||||
self._webserv_map[repository_id] = webserv
|
||||
return webserv
|
||||
|
||||
def _ugc_available(self, repository_id):
|
||||
webserv = self._get_webservice(repository_id)
|
||||
if webserv is None:
|
||||
return False
|
||||
return True
|
||||
|
||||
def _ugc_cache_icons(self, repository_id, package_names, cache):
|
||||
|
||||
webserv = self._get_webservice(repository_id)
|
||||
if webserv is None:
|
||||
return
|
||||
|
||||
for package_name in package_names:
|
||||
with Privileges():
|
||||
# sorry web service, we need data this way
|
||||
try:
|
||||
icon_docs = webserv.get_icons([package_name],
|
||||
cache = cache)[package_name]
|
||||
except WebService.WebServiceException as err:
|
||||
return
|
||||
|
||||
# get document urls, store to local cache
|
||||
for icon_doc in icon_docs:
|
||||
cache_key = package_name, icon_doc.repository_id()
|
||||
if cache_key in self.__pkg_ugc_icon_local_path_cache:
|
||||
const_debug_write(__name__,
|
||||
"_ugc_cache_icons: already in cache: %s" % (
|
||||
cache_key,))
|
||||
continue
|
||||
with Privileges():
|
||||
try:
|
||||
local_path = webserv.get_document_url(icon_doc)
|
||||
except ClientWebService.DocumentError as err:
|
||||
const_debug_write(__name__,
|
||||
"_ugc_cache_icons: document error: %s" % (
|
||||
err,))
|
||||
continue
|
||||
|
||||
try:
|
||||
self.__pkg_ugc_icon_cache.pop(cache_key)
|
||||
except KeyError:
|
||||
pass
|
||||
self.__pkg_ugc_icon_local_path_cache[cache_key] = local_path
|
||||
const_debug_write(__name__,
|
||||
"_ugc_cache_icons: pushed to cache: %s, %s" % (
|
||||
cache_key, local_path,))
|
||||
break
|
||||
|
||||
def __ugc_dnd_updates_clear_cache(self, *args):
|
||||
|
||||
const_debug_write(__name__, "EntropyPackageView, "
|
||||
"__ugc_dnd_updates_clear_cache called")
|
||||
|
||||
while True:
|
||||
try:
|
||||
key, repoid = self._ugc_dnd_cache_taint.pop()
|
||||
except KeyError:
|
||||
break
|
||||
self._entropy.UGC.get_docs(repoid, key)
|
||||
def _do_parallel():
|
||||
|
||||
self.__pkg_ugc_icon_cache.clear()
|
||||
self.__pkg_ugc_icon_call_cache.clear()
|
||||
self._ugc_pixbuf_map.clear()
|
||||
self._ugc_metadata_sync_exec_cache.clear()
|
||||
self._emit_ugc_update()
|
||||
fetch_map = {}
|
||||
while True:
|
||||
try:
|
||||
key, repoid = self._ugc_dnd_cache_taint.pop()
|
||||
except KeyError:
|
||||
break
|
||||
obj = fetch_map.setdefault(repoid, set())
|
||||
obj.add(key)
|
||||
|
||||
def _ugc_drag_data_received(self, view, context, x, y, selection, drop_id, etime):
|
||||
for repository_id, keys in fetch_map.items():
|
||||
self._ugc_cache_icons(repository_id, keys, False)
|
||||
|
||||
self.__pkg_ugc_icon_cache.clear()
|
||||
self._ugc_pixbuf_map.clear()
|
||||
self._ugc_metadata_sync_exec_cache.clear()
|
||||
self._emit_ugc_update()
|
||||
self.__pkg_ugc_icon_local_path_cache.clear()
|
||||
|
||||
th = ParallelTask(_do_parallel)
|
||||
th.start()
|
||||
|
||||
def _ugc_drag_data_received(self, view, context, x, y, selection, drop_id,
|
||||
etime):
|
||||
"""
|
||||
Callback function for drag_data_received event used for UGC interaction
|
||||
on Drag and Drop.
|
||||
@@ -1857,7 +1952,7 @@ class EntropyPackageView:
|
||||
obj.voted = 0.0
|
||||
return
|
||||
repository = obj.repoid
|
||||
if not self._entropy.UGC.is_repository_eapi3_aware(repository):
|
||||
if not self._ugc_available(repository):
|
||||
obj.voted = 0.0
|
||||
return
|
||||
atom = obj.name
|
||||
@@ -1868,8 +1963,80 @@ class EntropyPackageView:
|
||||
t = ParallelTask(self.vote_submit_thread, repository, key, obj)
|
||||
t.start()
|
||||
|
||||
def _ugc_login(self, webserv, repository):
|
||||
|
||||
def fake_callback(*args, **kwargs):
|
||||
return True
|
||||
|
||||
# use input box to read login
|
||||
input_params = [
|
||||
('username', _('Username'), fake_callback, False),
|
||||
('password', _('Password'), fake_callback, True)
|
||||
]
|
||||
login_data = self._entropy.input_box(
|
||||
"%s %s %s" % (
|
||||
_('Please login against'), repository, _('repository'),),
|
||||
input_params,
|
||||
cancel_button = True
|
||||
)
|
||||
if not login_data:
|
||||
return False
|
||||
|
||||
username, password = login_data['username'], login_data['password']
|
||||
with Privileges():
|
||||
webserv.add_credentials(username, password)
|
||||
try:
|
||||
webserv.validate_credentials()
|
||||
except WebService.AuthenticationFailed:
|
||||
okDialog(self.ui.main,
|
||||
_("Authentication error. Not logged in."))
|
||||
return False
|
||||
okDialog(self.ui.main,
|
||||
_("Successfully logged in."))
|
||||
return True
|
||||
|
||||
def vote_submit_thread(self, repository, key, obj):
|
||||
status, err_msg = self._entropy.UGC.add_vote(repository, key, int(obj.voted))
|
||||
|
||||
status = True
|
||||
err_msg = None
|
||||
|
||||
webserv = self._get_webservice(repository)
|
||||
if webserv is None:
|
||||
err_msg = _("Unsupported Service")
|
||||
status = False
|
||||
|
||||
if status:
|
||||
|
||||
with Privileges():
|
||||
try:
|
||||
status = webserv.add_vote(key, int(obj.voted))
|
||||
except WebService.AuthenticationRequired:
|
||||
def _do_login():
|
||||
logged_in = self._ugc_login(webserv, repository)
|
||||
if logged_in:
|
||||
# call myself again
|
||||
gobject.idle_add(self.vote_submit_thread,
|
||||
repository, key, obj)
|
||||
else:
|
||||
t = ParallelTask(self.refresh_vote_info, obj)
|
||||
t.start()
|
||||
return False
|
||||
gobject.idle_add(_do_login)
|
||||
return False
|
||||
except WebService.WebServiceException as err:
|
||||
err_msg = repr(err)
|
||||
status = False
|
||||
|
||||
if status:
|
||||
with Privileges():
|
||||
# need to refill local cache
|
||||
done = True
|
||||
try:
|
||||
webserv.get_votes([key], cache = False)
|
||||
except WebService.WebServiceException as err:
|
||||
# ouch! drop everything completely
|
||||
webserv._drop_cached("get_votes")
|
||||
done = False
|
||||
|
||||
if status:
|
||||
color = SulfurConf.color_good
|
||||
@@ -1878,19 +2045,16 @@ class EntropyPackageView:
|
||||
else:
|
||||
color = SulfurConf.color_error
|
||||
txt1 = _("Error registering vote")
|
||||
txt2 = err_msg
|
||||
txt2 = err_msg or _("Already voted")
|
||||
|
||||
msg = "<span foreground='%s'><b>%s</b></span>: %s" % (
|
||||
color, txt1, txt2,)
|
||||
|
||||
def do_refresh(msg):
|
||||
self.ui.status.push(STATUS_BAR_CONTEXT_IDS['UGC'],
|
||||
"%s: %s" % (txt1, txt2,))
|
||||
self.ui.UGCMessageLabel.show()
|
||||
self.ui.UGCMessageLabel.set_markup(msg)
|
||||
return False
|
||||
def remove_ugc_sts():
|
||||
self.ui.status.pop(STATUS_BAR_CONTEXT_IDS['UGC'])
|
||||
self.ui.UGCMessageLabel.set_markup("")
|
||||
self.ui.UGCMessageLabel.hide()
|
||||
return False
|
||||
@@ -1899,6 +2063,7 @@ class EntropyPackageView:
|
||||
gobject.timeout_add_seconds(20, remove_ugc_sts)
|
||||
t = ParallelTask(self.refresh_vote_info, obj)
|
||||
t.start()
|
||||
return False
|
||||
|
||||
def refresh_vote_info(self, obj):
|
||||
time.sleep(5)
|
||||
@@ -2045,12 +2210,12 @@ class EntropyPackageView:
|
||||
else:
|
||||
cell.set_property('foreground', None)
|
||||
|
||||
def _ugc_queue_run(self):
|
||||
def _ugc_icon_queue_run(self):
|
||||
|
||||
const_debug_write(__name__, "_ugc_queue_run called")
|
||||
const_debug_write(__name__, "_ugc_icon_queue_run called")
|
||||
|
||||
pkgs = set()
|
||||
queue = self._ugc_load_queue
|
||||
queue = self._ugc_icon_load_queue
|
||||
|
||||
while queue.qsize():
|
||||
try:
|
||||
@@ -2062,40 +2227,24 @@ class EntropyPackageView:
|
||||
|
||||
if pkgs:
|
||||
const_debug_write(__name__,
|
||||
"_ugc_queue_run, spawning fetch of: %s" % (pkgs,))
|
||||
self._spawn_ugc_metadata_fetch(pkgs)
|
||||
"_ugc_icon_queue_run, spawning fetch of: %s" % (pkgs,))
|
||||
self._spawn_ugc_icon_docs_fetch(pkgs)
|
||||
|
||||
|
||||
def _spawn_ugc_metadata_fetch(self, pkgs):
|
||||
def _spawn_ugc_icon_docs_fetch(self, pkgs):
|
||||
|
||||
def do_ugc_sync():
|
||||
pkg_map = {}
|
||||
for key, repoid in pkgs:
|
||||
const_debug_write(__name__,
|
||||
"_spawn_ugc_metadata_fetch, checking: %s, %s" % (
|
||||
key, repoid,))
|
||||
if self._entropy.UGC.UGCCache.is_alldocs_cached(key, repoid):
|
||||
const_debug_write(__name__,
|
||||
"_spawn_ugc_metadata_fetch, skipping !!: %s, %s" % (
|
||||
key, repoid,))
|
||||
continue
|
||||
outcome = self._entropy.UGC.get_docs(repoid, key)
|
||||
const_debug_write(__name__,
|
||||
"_spawn_ugc_metadata_fetch, get_docs() called: %s" % (
|
||||
outcome,))
|
||||
self.__pkg_ugc_icon_call_cache.clear()
|
||||
obj = pkg_map.setdefault(repoid, [])
|
||||
obj.append(key)
|
||||
|
||||
def do_fork():
|
||||
fork_function(do_ugc_sync, self._emit_ugc_update)
|
||||
for repoid, keys in pkg_map.items():
|
||||
self._ugc_cache_icons(repoid, keys, True)
|
||||
self._emit_ugc_update()
|
||||
|
||||
gobject.idle_add(do_fork, priority = gobject.PRIORITY_LOW)
|
||||
|
||||
def _spawn_ugc_icon_fetch(self, icon_doc, repoid):
|
||||
|
||||
def do_icon_fetch():
|
||||
self._entropy.UGC.UGCCache.store_document(icon_doc['iddoc'],
|
||||
repoid, icon_doc['store_url'])
|
||||
|
||||
fork_function(do_icon_fetch, self._emit_ugc_update)
|
||||
th = ParallelTask(do_ugc_sync)
|
||||
th.start()
|
||||
|
||||
def _get_cached_pkg_ugc_icon(self, pkg):
|
||||
|
||||
@@ -2109,9 +2258,12 @@ class EntropyPackageView:
|
||||
|
||||
cache_key = (key, repoid,)
|
||||
cached = self.__pkg_ugc_icon_cache.get(cache_key)
|
||||
if cached == -1:
|
||||
# unavailable
|
||||
return None
|
||||
if cached is not None:
|
||||
const_debug_write(__name__, "_get_cached_pkg_ugc_icon %s in RAM" % (
|
||||
cache_key,))
|
||||
#const_debug_write(__name__, "_get_cached_pkg_ugc_icon %s in RAM" % (
|
||||
# cache_key,))
|
||||
return cached
|
||||
|
||||
# validate variables...
|
||||
@@ -2120,38 +2272,41 @@ class EntropyPackageView:
|
||||
if repoid is None:
|
||||
return
|
||||
|
||||
icon_doc = self._entropy.UGC.UGCCache.get_icon_cache(key, repoid)
|
||||
if icon_doc is None:
|
||||
const_debug_write(__name__,
|
||||
"_get_cached_pkg_ugc_icon %s NOT on disk" % (
|
||||
cache_key,))
|
||||
# not cached
|
||||
return
|
||||
|
||||
const_debug_write(__name__,
|
||||
"_get_cached_pkg_ugc_icon %s on disk?" % (
|
||||
webserv = self._get_webservice(repoid)
|
||||
if webserv is None:
|
||||
const_debug_write(__name__, "_get_cached_pkg_ugc_icon %s unsup." % (
|
||||
cache_key,))
|
||||
return
|
||||
|
||||
store_path = self._entropy.UGC.UGCCache.get_stored_document(
|
||||
icon_doc['iddoc'], repoid, icon_doc['store_url'])
|
||||
|
||||
store_path = self.__pkg_ugc_icon_local_path_cache.get(cache_key)
|
||||
if store_path is None:
|
||||
# not cached
|
||||
called = self.__pkg_ugc_icon_call_cache.get(cache_key)
|
||||
if not called:
|
||||
self._spawn_ugc_icon_fetch(icon_doc, repoid)
|
||||
self.__pkg_ugc_icon_call_cache[cache_key] = True
|
||||
const_debug_write(__name__,
|
||||
"_get_cached_pkg_ugc_icon %s not cached on disk" % (
|
||||
cache_key,))
|
||||
return
|
||||
|
||||
if not (os.access(store_path, os.R_OK) and os.path.isfile(store_path)):
|
||||
# not cached
|
||||
const_debug_write(__name__,
|
||||
"_get_cached_pkg_ugc_icon %s path not available" % (
|
||||
cache_key,))
|
||||
return
|
||||
with Privileges():
|
||||
# sorry web service, we need data this way
|
||||
try:
|
||||
icon_docs = webserv.get_icons([key], cache = True,
|
||||
cached = True)[key]
|
||||
except WebService.CacheMiss as err:
|
||||
#const_debug_write(__name__,
|
||||
# "_get_cached_pkg_ugc_icon %s NOT cached yet" % (
|
||||
# cache_key,))
|
||||
self.__pkg_ugc_icon_cache[cache_key] = -1
|
||||
return
|
||||
|
||||
# get document urls, store to local cache
|
||||
for icon_doc in icon_docs:
|
||||
local_path = icon_doc.local_document()
|
||||
if local_path is None:
|
||||
continue
|
||||
store_path = local_path
|
||||
break
|
||||
|
||||
if store_path is None:
|
||||
#const_debug_write(__name__,
|
||||
# "_get_cached_pkg_ugc_icon %s NOT cached yet (2)" % (
|
||||
# cache_key,))
|
||||
self.__pkg_ugc_icon_cache[cache_key] = -1
|
||||
return
|
||||
|
||||
icon_path = store_path + ".sulfur_icon_small"
|
||||
pixbuf = self._ugc_pixbuf_map.get(icon_path)
|
||||
@@ -2165,7 +2320,8 @@ class EntropyPackageView:
|
||||
if not (os.path.isfile(icon_path) and \
|
||||
os.access(icon_path, os.R_OK)):
|
||||
try:
|
||||
resize_image(self._get_row_height(), store_path,
|
||||
# keep some margin... -5
|
||||
resize_image(self._get_row_height() - 5, store_path,
|
||||
icon_path)
|
||||
except (ValueError, OSError, IOError, gobject.GError):
|
||||
# OSError = source file moved while copying
|
||||
@@ -2191,52 +2347,63 @@ class EntropyPackageView:
|
||||
def __new_ugc_pixbuf_stash_fetch(self, pkg):
|
||||
# stash to queue for loading from WWW if required
|
||||
|
||||
const_debug_write(__name__,
|
||||
"__new_ugc_pixbuf_stash_fetch called: %s" % (
|
||||
pkg,))
|
||||
#if const_debug_enabled():
|
||||
# const_debug_write(__name__,
|
||||
# "__new_ugc_pixbuf_stash_fetch called: %s" % (
|
||||
# pkg,))
|
||||
|
||||
if not self._ugc_status:
|
||||
const_debug_write(__name__,
|
||||
"__new_ugc_pixbuf_stash_fetch UGC STATUS FALSE!")
|
||||
if const_debug_enabled():
|
||||
const_debug_write(__name__,
|
||||
"__new_ugc_pixbuf_stash_fetch UGC STATUS FALSE!")
|
||||
return
|
||||
|
||||
const_debug_write(__name__,
|
||||
"__new_ugc_pixbuf_stash_fetch going on for: %s" % (
|
||||
pkg,))
|
||||
#if const_debug_enabled():
|
||||
# const_debug_write(__name__,
|
||||
# "__new_ugc_pixbuf_stash_fetch going on for: %s" % (
|
||||
# pkg,))
|
||||
|
||||
try:
|
||||
repoid = pkg.repoid
|
||||
sync_item = (pkg.key, repoid)
|
||||
except (ProgrammingError, OperationalError) as err:
|
||||
const_debug_write(__name__,
|
||||
"__new_ugc_pixbuf_stash_fetch, ouch: %s" % (
|
||||
repr(err),))
|
||||
if const_debug_enabled():
|
||||
const_debug_write(__name__,
|
||||
"__new_ugc_pixbuf_stash_fetch, ouch: %s" % (
|
||||
repr(err),))
|
||||
return
|
||||
if sync_item in self._ugc_metadata_sync_exec_cache:
|
||||
const_debug_write(__name__,
|
||||
"__new_ugc_pixbuf_stash_fetch: already in cache: %s" % (
|
||||
sync_item,))
|
||||
#if const_debug_enabled():
|
||||
# const_debug_write(__name__,
|
||||
# "__new_ugc_pixbuf_stash_fetch: already in cache: %s" % (
|
||||
# sync_item,))
|
||||
return
|
||||
|
||||
self._ugc_metadata_sync_exec_cache.add(sync_item)
|
||||
if not self._entropy.UGC.is_repository_eapi3_aware(repoid):
|
||||
const_debug_write(__name__,
|
||||
"__new_ugc_pixbuf_stash_fetch: repository not EAPI3 aware: %s" % (
|
||||
repoid,))
|
||||
if not self._ugc_available(repoid):
|
||||
if const_debug_enabled():
|
||||
const_debug_write(__name__,
|
||||
"__new_ugc_pixbuf_stash_fetch: "
|
||||
"repository not Web Services aware: %s" % (
|
||||
repoid,))
|
||||
return
|
||||
|
||||
const_debug_write(__name__,
|
||||
"__new_ugc_pixbuf_stash_fetch: enqueue %s" % (sync_item,))
|
||||
if const_debug_enabled():
|
||||
const_debug_write(__name__,
|
||||
"__new_ugc_pixbuf_stash_fetch: enqueue %s" % (sync_item,))
|
||||
|
||||
try:
|
||||
self._ugc_load_queue.put_nowait(sync_item)
|
||||
const_debug_write(__name__,
|
||||
"__new_ugc_pixbuf_stash_fetch: enqueued!! %s" % (sync_item,))
|
||||
self._ugc_icon_load_queue.put_nowait(sync_item)
|
||||
if const_debug_enabled():
|
||||
const_debug_write(__name__,
|
||||
"__new_ugc_pixbuf_stash_fetch: enqueued!! %s" % (
|
||||
sync_item,))
|
||||
except self.queue_full_exception as err:
|
||||
# argh! queue full!
|
||||
const_debug_write(__name__,
|
||||
"__new_ugc_pixbuf_stash_fetch: ARGH QUEUE FULL %s" % (
|
||||
sync_item,))
|
||||
if const_debug_enabled():
|
||||
const_debug_write(__name__,
|
||||
"__new_ugc_pixbuf_stash_fetch: ARGH QUEUE FULL %s" % (
|
||||
sync_item,))
|
||||
pass
|
||||
|
||||
def new_ugc_pixbuf(self, column, cell, model, myiter):
|
||||
|
||||
Reference in New Issue
Block a user