#!/usr/bin/python3
import sys, os, locale, signal, re, pickle
import gi, subprocess, time, threading
from locale import gettext as _
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GLib, Pango
if os.path.exists('updaterlib.py'):
  from updaterlib import *
else:
  from update_applet.updaterlib import *

import warnings
warnings.filterwarnings("ignore", category=DeprecationWarning)

INSTALL = True
PULSE = False
locale.bindtextdomain(COMMON.DOMAIN, COMMON.LOCALE_DIR)
locale.textdomain(COMMON.DOMAIN)

install_cmd = 'pkexec /usr/libexec/rpmgrab_admin.helper install '
reinstall_cmd = 'pkexec /usr/libexec/rpmgrab_admin.helper reinstall '
repoquery_cmd = 'pkexec /usr/libexec/rpmgrab.helper repoquery '
refresh_cmd = 'pkexec /usr/libexec/rpmgrab.helper refresh '
dnfinfo_cmd = [ 'pkexec', '/usr/libexec/rpmgrab.helper', 'info' ]
provide_cmd = [ 'pkexec', '/usr/libexec/rpmgrab.helper', 'provide' ]
check_remove_cmd = [ 'pkexec', '/usr/libexec/rpmgrab.helper', 'check_remove' ]
remove_cmd = 'pkexec /usr/libexec/rpmgrab_admin.helper remove '

UI = os.path.join(COMMON.getpath(), COMMON.UI)

ICON = os.path.join('/usr/share/icons', 'rpmgrab.svg')
cfgdir = os.environ['HOME'] + '/.config/rpmgrab'

config = {}
config['show_log'] = False

def pickle_write():
    with open(cfgdir + '/dump', 'wb') as f:
       pickle.dump(config, f)

class RPMVersion:
    """Класс для сравнения RPM-версий в формате epoch:version-release"""
    @debug_decorator
    def __init__(self, version):
        format_error = f"RPMVersion expected: epoch:version-release', got: {version}"
        if ':' not in version:
            raise ValueError(format_error)

        epoch_str, rest = version.split(':', 1)
        self.epoch = int(epoch_str)

        if '-' not in rest:
            raise ValueError(format_error)

        self.version, self.release = rest.rsplit('-', 1)
        self.raw_version = version
        self._parts = self._build_parts()

    def _split_component(self, comp):
        if not comp:
            return []

        parts = []
        for part in comp.split('.'):
            if part.isdigit():
                parts.append(int(part))
            else:
                for sub in re.split(r'(\d+)', part):
                    if sub and sub.isdigit():
                        parts.append(int(sub))
                    elif sub:
                        parts.append(sub)
        return parts

    def _build_parts(self):
        parts = [self.epoch]
        parts.extend(self._split_component(self.version))
        parts.extend(self._split_component(self.release))
        return parts

    @debug_decorator
    def __eq__(self, other):
        return self._parts == other._parts

    @debug_decorator
    def __lt__(self, other):
        for a, b in zip(self._parts, other._parts):
            if a != b:
                if type(a) == type(b):
                    return a < b
                # Числа всегда меньше строк
                return isinstance(a, int)

        return len(self._parts) < len(other._parts)

    def __gt__(self, other):
        return not (self < other or self == other)

    def __str__(self):
        return self.raw_version


class Remove:
    @debug_decorator
    def __init__(self, rpms, app):
        app.install_button.set_sensitive(False)
        app.install_button.set_label(_('Remove rpm'))
        app.progress.set_text(_('Removing'))
        self.cmd = remove_cmd
        self.rpms = rpms if isinstance(rpms, list) else [rpms]
        self.list(app)
        self.not_found = [rpm for rpm in self.rpms if not self.inst_check(rpm)]
        if self.not_found:
            self.rpms = list(set(self.rpms) - set(self.not_found))
            echo(app, '\n==> ' + _('Some packages from the RPM list are not installed!'),
                 _('Some packages from the RPM list were not found!'))
            for a in self.not_found:
                 echo(app, a, _('Some packages from the RPM list were not found!'))
        refresh()
        if self.rpms:
            self.requires = self.get_dnf_remove_list(self.rpms) - set(self.rpms)
            if self.requires:
                echo(app, '\n==> ' + _('Packages that will also be removed:'),
                     _('Found required packages'))
                for a in self.requires:
                    echo(app, a, _('Click "Info" to see the full list of packages marked for removal'))
            if self.rpms:
                app.window.set_title(_('RPMGRAB - remove: ') + ' ,'.join(self.rpms)[:20] + '...')
                app.install_button.set_sensitive(True)
        else:
            app.window.set_title(_('RPMGRAB - nothing to do'))
            echo(app, '\n==> ' + _('Nothing to remove.'),
                 _('Nothing to remove.'))

    @debug_decorator
    def get_dnf_remove_list(self, packages):
        command = check_remove_cmd + packages
        packages = []
        in_removing = False
        need_env = os.environ.copy()
        need_env["LANGUAGE"] = "C"
        result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, env=need_env)
        for line in result.stdout.split('\n'):
            line = line.strip()

            if line.startswith('Removing:'):
                in_removing = True
                continue
            elif 'Transaction Summary' in line:
                break
            if in_removing and len(line.split()) > 3  and line.split()[3].startswith('@'):
                pkg_name = line.split()[0]
                packages.append(pkg_name)
        return set(packages)

    @debug_decorator
    def inst_check(self, rpm):
        cmd = [ 'rpm', '-q' ]
        need_env = os.environ.copy()
        need_env["LANGUAGE"] = "C"
        result = subprocess.run(cmd + [rpm], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, env=need_env)
        return not result.returncode

    def list(self, app):
        echo(app, '==> ' + _('RPM package names to remove: '), _('Remove mode'))
        for package in self.rpms:
            echo(app, package, _('Remove mode'))

    @debug_decorator
    def action(self,app):
        start_pulse(app, True)
        GLib.idle_add(app.install_button.hide)

        if self.rpms and self.not_found:
            choose = dialog(
                first=_('Some packages were not found.') if len(self.not_found) > 1 else _('Package not found:'),
                second=', '.join(self.not_found),
                btn=[_('Continue'), 1, _('Abort'), 0]
            )
            if choose:
                self.not_found = []
                self.action(app)
                return False

        elif self.requires:
            list_part = list(self.requires)[:10]
            else_part = len(self.requires) - len(list_part)
            else_text = ' {} {} {}'.format( _('and'), str(else_part), _('more packages.')) if else_part > 0 else ''
            choose = dialog(
                first=_('These packages will also be removed:') if len(self.requires) > 1 else _('This package will also be removed:'),
                second=', '.join(list_part) + else_text,
                btn=[_('Continue'), 1, _('Abort'), 0]
            )
            if choose:
                self.requires = []
                self.action(app)
                return False

        elif self.rpms and not self.not_found:
            clear()
            if not runit(app, f'{self.cmd} {" ".join(self.rpms)}', _('Removing RPM packages')):
                echo(app, 'ERROR!!!', 'ERROR: ' + self.cmd)
                notify_send(
                    ', '.join(self.rpms) + _(' - removal failed'),
                _('Try again later, or use the system package manager'),
                'warning',
                None,
                None
                )
            else:
                start_pulse(app, False)
                app.progress.set_fraction(1.0)
                app.progress.set_text(_('Complete'))
                refresh()
                echo(app, _('Complete'),
                    _('RPM removal complete: ') + ", ".join(self.rpms[:5]) + ('...' if len(self.rpms) > 5 else '.') )
                return False

        GLib.idle_add(app.install_button.show)
        start_pulse(app, False)
        app.progress.set_fraction(0)


class Rpms:
    @debug_decorator
    def __init__(self, rpms, app):
        self.rpms = rpms
        self.absrpms = list(map(os.path.abspath, rpms))
        self.list(app)

        if not any(map(os.path.exists, self.absrpms)):
            message = _('Batch installation from a repository is not available with rpmgrab.')
            notify_send(
                message,
                ', '.join(self.rpms),
                'warning',
                None,
                None
            )
            echo(app, message, message)
            return None

        if not all(map(os.path.exists, self.absrpms)):
            message = _('Some files from rpms list not found:')
            notify_send(
                message,
                ', '.join(self.rpms),
                'warning',
                None,
                None
            )
            echo(app, message, message)
            return None

        self.rpms = True
        self.installed = self.check_installed(app)

        if self.installed:
            echo(app, '\n==> ' + _('Already installed packages:'),
                 _('Found already installed'))

            self.strlist = ''
            for package in self.installed:
                version_info = f"{package['name']}: {package['old_ver']} --> {package['new_ver']}"
                self.strlist += version_info + '\n'
                echo(app, version_info, _('Found already installed packages'))

        app.install_button.set_sensitive(True)
        app.install_button.set_label(_('Install list of rpms'))

    @debug_decorator
    def check_installed(self, app):
        """Check which packages are already installed"""
        installed = []

        for package in self.absrpms:
            info = info_to_dict(package)
            oldinfo = info_to_dict(info['Name'])

            if oldinfo:
                old_epoch = oldinfo.get('Epoch', '0')
                new_epoch = info.get('Epoch', '0')

                new_version = f"{new_epoch}:{info['Version']}-{info['Release']}"
                old_version = f"{old_epoch}:{oldinfo['Version']}-{oldinfo['Release']}"

                if old_version >= new_version:
                    installed.append({
                        'name': info['Name'],
                        'file': package,
                        'old_ver': old_version,
                        'new_ver': new_version
                    })

        return installed

    def list(self, app):
        echo(app, '==> ' + _('RPMS list: '), _('Multiple install'))
        for package in self.absrpms:
            echo(app, package, _('Multiple install'))

    @debug_decorator
    def action(self, app):
        clear()
        start_pulse(app, True)
        GLib.idle_add(app.install_button.hide)

        if self.installed:
            reinstall = [
                item['file'] for item in self.installed
                if item['old_ver'] == item['new_ver']
            ]

            newlist = [rpm for rpm in self.absrpms if rpm not in reinstall]
            self.inst = " ".join(f'"{item}"' for item in newlist)
            self.reinst = " ".join(f'"{item}"' for item in reinstall)

            choose = dialog(
                first=_('Found already installed packages'),
                second=self.strlist,
                btn=[_('Skip'), 0, _('Reinstall'), 1, _('Abort'), 3]
            )

            if choose == 1:
                if not runit(app, f'{reinstall_cmd} {self.reinst}',
                             _('Reinstall rpm packages')):
                    echo(app, 'ERROR!!!', 'ERROR: ' + reinstall_cmd + _(" <packages list>"))
                    GLib.idle_add(app.install_button.show)
                    start_pulse(app, False)
                    app.progress.set_fraction(0.0)
                    notify_send(
                        _('Reinstallation failed'),
                        _('Try later, or use system package manager'),
                        'warning',
                        None,
                        None
                    )
                    return False
                else:
                    echo(app, '', _("Reinstall done"))

            elif choose == 3:
                exit()

        else:
            self.inst = " ".join(f'"{item}"' for item in self.absrpms)

        if self.inst:
            if not runit(app, f'{install_cmd} {self.inst}',
                         _('Install rpm packages')):
                refresh()
                echo(app, 'ERROR!!!', 'ERROR: ' + install_cmd + _(" <packages list>"))
                GLib.idle_add(app.install_button.show)
                start_pulse(app, False)
                app.progress.set_fraction(0.0)
                notify_send(
                    _('Installation failed'),
                    _('Try later, or use system package manager'),
                    'warning',
                    None,
                    None
                )
                return False
        else:
            echo(app, '\n==> ' + _('No packages selected to install'),
                 _('No packages selected to install'))

        start_pulse(app, False)
        app.progress.set_fraction(1.0)
        app.progress.set_text(_('Complete'))
        refresh()
        echo(app, '', _("Complete"))
        return False

class Rpm:
    @debug_decorator
    def __init__(self, rpm, app):
        start_pulse(app, True)

        self.cmd = install_cmd
        self.rpm = self.get_rpm(rpm, app)
        self.usednf = False

        if os.path.isfile(self.rpm):
            self.info = info_to_dict(self.rpm)
        else:
            self.usednf = True
            runit(app, f'timeout 60s {refresh_cmd}', _('Update dnf metadata'))
            self.info = info_to_dict(self.rpm, cmd='dnf')

        if not self.info:
            self.rpm = None
            app.window.set_title(_('RPMGRAB - nothing to do'))
            echo(app, '\n==> ' + _('Package not found: ') + rpm,
                 _('Nothing to install, sorry.'))
            start_pulse(app, False)
            app.progress.set_fraction(0)
            return None

        echo(app, '==> ' + _('Meta info from RPM package: '),
             _('Package info: ') + self.info['Name'])
        if os.path.isfile(self.rpm):
           echo(app, 'FILE: ' + self.rpm, '')
        app.window.set_title(f"RpmGrab: {self.info['Name']}")

        for key, val in self.info.items():
            echo(app, f'{key.upper()}: {val}', _("Rpm info"))
        
        self.req(app)
        self.prov(app)
        self.list(app)
        
        oldinfo = info_to_dict(self.info['Name'])
        if oldinfo:
            old_epoch = oldinfo.get('Epoch', '0')
            new_epoch = self.info.get('Epoch', '0')

            old_version = RPMVersion(f"{old_epoch}:{oldinfo['Version']}-{oldinfo['Release']}")
            new_version = RPMVersion(f"{new_epoch}:{self.info['Version']}-{self.info['Release']}")
            dprint(f'old: {old_version}')
            dprint(f'new: {new_version}')
            if old_version == new_version:
                self.cmd = reinstall_cmd
                app.install_button.set_label(_('Reinstall package'))
            elif old_version < new_version:
                app.install_button.set_label(_('Update package'))
            else:
                app.install_button.set_label(_('Downgrade'))
                # Без GLib.idle_add падает с ошибкой X сервера
                GLib.idle_add(
                    lambda new=new_version, old=old_version: (
                        dialog(
                            first=_("Warning: Downgrade Attempt"),
                            second=_(
                                "You are trying to install a package version ({new}) "
                                "that is lower than the currently installed version ({old}). "
                                "This may cause compatibility issues."
                            ).format(new=new, old=old),
                            btn=[_("I Understand"), 1]
                        ),
                        False
                    )[1]
                )
        else:
            app.install_button.set_label(_('Install package'))

        start_pulse(app, False)
        app.progress.set_fraction(0.0)
        app.install_button.set_sensitive(True)
        time.sleep(1) # race condition
        refresh()
        echo(app, ' ', f"{app.install_button.get_label()}: {self.info['Name']}")


    @debug_decorator
    def get_rpm(self, rpm, app):
        if rpm.startswith('http'):
            echo(app, '==> ' + _('Download rpm:\n    ') + rpm,
                 _('Download rpm: ') + rpm)
            rpmfile = download_file(rpm, '.rpm', '/tmp', app=app)
            return rpmfile

        if rpm.endswith('.rpm') and os.path.isfile(rpm):
            rpmfile = os.path.abspath(rpm)
            return rpmfile
        try:
            command = provide_cmd + [rpm]
            result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
            rpmname = result.stdout.split('\n')[0].strip().split()[0]
            if rpmname:
                return rpmname
        except Exception as e:
            dprint(e)
            return rpm

    def info(self, app):
        runit(app, f'timeout 10s rpm -q --info "{self.rpm}"', _('Rpm info: '))

    def req(self, app):
        echo(app, '\n', _('Requires: ') + self.rpm)
        if self.usednf:
            runit(app, f'timeout 10s {repoquery_cmd} --requires -q "{self.rpm}"',
                  _('Requires: '))
        else:
            runit(app, f'timeout 10s rpm -q --requires "{self.rpm}"',
                  _('Requires: '))

        echo(app, '\n', _('Recommends: ') + self.rpm)
        if self.usednf:
            runit(app, f'timeout 10s {repoquery_cmd} --recommends -q "{self.rpm}"',
                  _('Recommends: '))
        else:
            runit(app, f'timeout 10s rpm -q --recommends "{self.rpm}"',
                  _('Recommends: '))

    def prov(self, app):
        echo(app, '\n', _('Provides: ') + self.rpm)
        if self.usednf:
            runit(app, f'timeout 10s {repoquery_cmd} --provides -q "{self.rpm}"',
                  _('Provides: '))
        else:
            runit(app, f'timeout 10s rpm -q --provides "{self.rpm}"',
                  _('Provides: '))

    def list(self, app):
        echo(app, '\n', _('RPM list: ') + self.rpm)
        if self.usednf:
            runit(app, f'timeout 10s {repoquery_cmd} --list -q "{self.rpm}"',
                  _('RPM list: '))
        else:
            runit(app, f'timeout 10s rpm -ql "{self.rpm}"',
                  _('RPM list: '))

    @debug_decorator
    def action(self, app):
        clear()
        start_pulse(app, True)
        GLib.idle_add(app.install_button.hide)

        if not runit(app, f'{self.cmd} "{self.rpm}"', _('Install: ') + self.rpm):
            refresh()
            echo(app, 'ERROR!!!', 'ERROR: ' + install_cmd)
            GLib.idle_add(app.install_button.show)
            start_pulse(app, False)
            app.progress.set_fraction(0.0)
            notify_send(
                self.rpm + _(': installation failed'),
                _('Try later, or use system package manager'),
                'warning',
                None,
                None
            )
        else:
            start_pulse(app, False)
            app.progress.set_fraction(1.0)
            app.progress.set_text(_('Complete'))
            refresh()
            echo(app, _('Complete'),
                 _('Install complete: ') + os.path.basename(self.rpm))

        return False

@debug_decorator
def info_to_dict(rpm_name, cmd='rpm'):
    if cmd == 'rpm':
        command = ['rpm', '-qi', rpm_name]
    else:
        command = dnfinfo_cmd + [rpm_name]

    need_env = os.environ.copy()
    need_env["LANGUAGE"] = "C"
    result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, env=need_env)
    if result.returncode != 0:
      return None
    info_dict = {}
    lines = result.stdout.splitlines()
    i = 0
    while i < len(lines):
      line = lines[i]
      if line.startswith('Description'):
          key = 'Description'
          value_parts = [line.split(':', 1)[1].strip()] if ':' in line else []
          i += 1
          while i < len(lines):
            if not lines[i].strip():
                break
            value_parts.append(lines[i].strip())
            i += 1
          info_dict[key] = '\n'.join(value_parts)
      else:
        match = re.match(r'^([^:]+)\s*:\s*(.*)$', line)
        if match:
            key = match.group(1).strip()
            value = match.group(2).strip()
            info_dict[key] = value
        i += 1
    return info_dict

@debug_decorator
def clear():
    global INSTALL
    app.window.set_title(_('RpmGrab - simple rpm installator gui'))
    app.textbuffer.set_text('\n')
    app.statusbar.push(app.context_id, '')
    app.progress.set_pulse_step(0.2)
    app.progress.set_text(_('Install'))
    app.text_window.hide()
    app.exit_button.set_label(_('Exit'))
    app.install_button.set_label(_('Install'))
    app.install_button.set_sensitive(False)
    app.pwf_button.hide()
    app.install_button.show()
    start_pulse(app, False)
    app.log_chkbx.set_label(_('Info'))

    if config['show_log']:
        app.log_chkbx.set_active(True)
        app.text_window.show()
    else:
        app.log_chkbx.set_active(False)
        app.text_window.hide()

def exit(*args):
  Gtk.main_quit()

class WinHandler:
    def on_CHECK_HALT_activate(*args):
        pass
    def on_exit_button_dialog_clicked(*args):
        pass
    def on_release_eventbox_enter_notify_event(self, *args):
        pass
    def on_release_eventbox_leave_notify_event(self, *args):
        pass
    def on_release_eventbox_button_press_event(self, *args):
        pass

    def on_show_log_toggled(self, button):
      global config
      if app.log_chkbx.get_active():
          app.text_window.show()
          config['show_log'] = True
      else:
          w, h = app.window.get_size()
          app.text_window.hide()
          app.window.resize(w, app.window.get_preferred_height()[1])
          config['show_log'] = False
      pickle_write()

    def onSUBMIT(self, button):
        global INSTALL
        bat = powercheck()
        if bat < 10:
            if not  dialog(first=_("Attention!\nThe battery charge status is low: ") + f'{bat}%',
                           second=_("Continue?"), btn=[Gtk.STOCK_YES, 1, Gtk.STOCK_NO, 0 ] ):
                return
        GLib.idle_add(lambda : rpm.action(app))

    def onEXIT(self, button):
        exit()

class Applet:
  def __init__(self):

    # window
    signal.signal(signal.SIGINT, signal.SIG_DFL)
    builder = Gtk.Builder()
    self.builder = builder
    builder.set_translation_domain(COMMON.DOMAIN)
    builder.add_from_file(UI)

    textaria = builder.get_object('TEXTAREA')
    textaria.override_font(Pango.FontDescription('Monospace 10'))
    self.textbuffer = textaria.get_buffer()

    self.progress = builder.get_object('PROGRESS')
    self.statusbar = builder.get_object('STATUS')
    self.text_window = builder.get_object('SCROLL')
    self.context_id = self.statusbar.get_context_id('updater')

    self.log_chkbx = builder.get_object('show_log')
    self.install_button = builder.get_object('SUBMIT')
    self.exit_button = builder.get_object('EXIT')
    self.pwf_button = builder.get_object('CHECK_HALT')
    builder.connect_signals(WinHandler())
    self.scroll = builder.get_object('SCROLL')
    self.v = self.scroll.get_vadjustment()
    self.h = self.scroll.get_hadjustment()

    self.window = builder.get_object('window_main')
    self.window.set_icon_from_file(ICON)
    self.window.connect("destroy", Gtk.main_quit)

  def run(self):
    self.window.show_all()
    self.pwf_button.hide()
    Gtk.main()

def scroll_back(app):
  app.v.set_value(0)
  app.h.set_value(0)
  return False

def HLP():
    print(_("""Usage: rpmgrab [OPTIONS] [RPM_FILE|PACKAGE_NAME...]
Simple GUI RPM installer

Options:
  --help     Show this help message
  --force    Install immediately without confirmation
  --version  Show version information
  --remove   Remove mode

Examples:
  rpmgrab package.rpm
  rpmgrab package-name
  rpmgrab http://example.com/package.rpm
  rpmgrab package1.rpm package2.rpm
  rpmgrab --force package.rpm
  rpmgrab rpmgrab://name/package-name
  rpmgrab --remove package-name"""))
    sys.exit(0)

if __name__ == '__main__':
  if os.path.exists(cfgdir + '/dump'):
    try:
      with open(cfgdir + '/dump', 'rb') as f:
        config = pickle.load(f)
    except pickle.UnpicklingError as e:
      print(f"Pickle read data error: {e}")
      try:
        os.remove(cfgdir + '/dump')
      except:
            pass
    except PermissionError as e:
          print(f"Permissions error: {e}")
  else:
    os.makedirs(cfgdir, exist_ok=True)
    pickle_write()

  notify_init('RpmGrab')
  app = Applet()
  clear()
  force = False
  remove = False
  rpmfile = []

  # Parse command line arguments
  i = 1
  while i < len(sys.argv):
      arg = sys.argv[i]
      if arg == '--help':
          HLP()
      elif arg == '--force':
          force = True
      elif arg == '--remove':
          remove = True
      elif arg == '--version':
          print("RpmGrab 1.0")
          sys.exit(0)
      elif arg.startswith('file://'):
          filepath = arg[7:]
          if filepath.startswith('///'):
              filepath = filepath[2:]
          rpmfile.append(filepath)
      elif arg.startswith('rpmgrab://'):
          try:
              protocol, rest = arg[10:].split('/', 1)
              if protocol == 'name':
                  rpmfile.append(rest)
              elif protocol in ['http', 'https', 'ftp']:
                  rpmfile.append(f"{protocol}://{rest}")
              else:
                  print(f"Unknown protoсol: {protocol}")
                  sys.exit(1)
          except ValueError:
              print(f"Illegal format: {arg}")
              sys.exit(1)
      else:
          rpmfile.append(arg)
      i += 1

  if not rpmfile:
      rpmfile = dialog(first=_('Enter rpm file'), entry='yes')
      if not rpmfile:
          quit()
      if isinstance(rpmfile, str):
          rpmfile = [rpmfile]

  rpm = None
  def rpm_init():
    global rpm
    global force
    rpm = threading_me(Rpm, rpmfile[0], app)
    if not force:
      GLib.timeout_add_seconds(1, lambda : scroll_back(app))
    else:
      WinHandler().onSUBMIT(None)
    return False

  def rpms_init():
    global rpm
    rpm = threading_me(Rpms, rpmfile, app)
    GLib.timeout_add_seconds(1, lambda : scroll_back(app))
    return False
  dprint(str(rpmfile))

  def remove_init():
    global rpm
    rpm = threading_me(Remove, rpmfile, app)
    GLib.timeout_add_seconds(1, lambda : scroll_back(app))
    return False
  dprint(str(rpmfile))

  if not remove:
      if len(rpmfile) > 1:
        GLib.idle_add(rpms_init)
      else:
        GLib.idle_add(rpm_init)
  else:
      GLib.idle_add(remove_init)
  app.run()

