示例#1
0
class Antiviral(Gtk.Window):

    def __init__(self, from_filebrowser=False, folders=[]):
        Gtk.Window.__init__(self)
        self.set_title(_('Antiviral'))
        self.set_modal(True)
        #
        try:
            self.scanner = pyclamd.ClamdUnixSocket()
            self.scanner.ping()
        except pyclamd.ConnectionError:
            self.scanner = pyclamd.ClamdNetworkSocket()
            try:
                self.scanner.ping()
            except pyclamd.ConnectionError as e:
                print(e)
                exit(0)
        # print(self.scanner.reload())
        print(self.scanner.stats())
        #
        self.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
        self.set_title(comun.APP)
        self.set_icon_from_file(comun.ICON)
        self.connect('destroy', self.on_close_application)
        #
        vbox = Gtk.VBox(spacing=5)
        vbox.set_border_width(5)
        self.add(vbox)
        #
        frame0 = Gtk.Frame()
        vbox.pack_start(frame0, True, True, 0)
        vbox0 = Gtk.VBox(spacing=5)
        vbox0.set_border_width(5)
        frame0.add(vbox0)
        #
        label1 = Gtk.Label()
        label1.set_text(_('ClamAV version')+': ' +
                        self.scanner.version().split(' ')[1].split('/')[0])
        label1.set_alignment(0, 0.5)
        vbox0.pack_start(label1, False, False, 0)
        #
        frame1 = Gtk.Frame()
        vbox.pack_start(frame1, True, True, 0)
        hbox1 = Gtk.HBox(spacing=5)
        hbox1.set_border_width(5)
        frame1.add(hbox1)
        #
        vbox0 = Gtk.VBox()
        hbox1.pack_start(vbox0, False, False, 0)

        button_b0 = ButtonWithTextAndIcon(
            _('Scan home'), Gtk.Image.new_from_stock(
                Gtk.STOCK_FIND, Gtk.IconSize.BUTTON))
        button_b0.set_tooltip_text(_('Scan home now'))
        button_b0.connect('clicked', self.on_button_scan_home_clicked)
        vbox0.pack_start(button_b0, False, False, 0)

        button_b1 = ButtonWithTextAndIcon(
            _('Scan folders'), Gtk.Image.new_from_stock(
                Gtk.STOCK_FIND, Gtk.IconSize.BUTTON))
        button_b1.set_tooltip_text(_('Scan selected folders now'))
        button_b1.connect('clicked', self.on_button_scan_clicked)
        vbox0.pack_start(button_b1, False, False, 0)

        button_quit = ButtonWithTextAndIcon(
            _('Exit'), Gtk.Image.new_from_stock(
                Gtk.STOCK_QUIT, Gtk.IconSize.BUTTON))
        button_quit.set_tooltip_text(_('Exit'))
        button_quit.connect('clicked', self.on_close_application)
        vbox0.pack_end(button_quit, False, False, 0)
        #
        button_about = ButtonWithTextAndIcon(
            _('About'), Gtk.Image.new_from_stock(
                Gtk.STOCK_ABOUT, Gtk.IconSize.BUTTON))
        button_quit.set_tooltip_text(_('About'))
        button_about.connect('clicked', self.on_button_about_clicked)
        vbox0.pack_end(button_about, False, False, 0)
        #
        button_update = ButtonWithTextAndIcon(
            _('Update'), Gtk.Image.new_from_stock(
                Gtk.STOCK_REFRESH, Gtk.IconSize.BUTTON))
        button_update.set_tooltip_text(_('Update virus database'))
        button_update.connect('clicked', self.on_button_update_clicked)
        vbox0.pack_end(button_update, False, False, 0)

        scrolledwindow = Gtk.ScrolledWindow()
        scrolledwindow.set_policy(
            Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
        scrolledwindow.set_shadow_type(Gtk.ShadowType.ETCHED_OUT)
        scrolledwindow.set_size_request(500, 300)
        hbox1.pack_start(scrolledwindow, True, True, 0)
        model = Gtk.ListStore(bool, bool, str)
        self.treeview = Gtk.TreeView()
        self.treeview.set_model(model)
        scrolledwindow.add(self.treeview)
        crt0 = Gtk.CellRendererToggle()
        crt0.set_property('activatable', True)
        column0 = Gtk.TreeViewColumn(_('Scan'), crt0, active=0)
        crt0.connect("toggled", self.toggled_cb, (model, 0))
        self.treeview.append_column(column0)
        crt1 = Gtk.CellRendererToggle()
        crt1.set_property('activatable', True)
        column1 = Gtk.TreeViewColumn(_('Rec.'), crt1, active=1)
        crt1.connect("toggled", self.toggled_cb, (model, 1))
        self.treeview.append_column(column1)
        #
        column = Gtk.TreeViewColumn(
            _('Folder'), Gtk.CellRendererText(), text=2)
        self.treeview.append_column(column)

        #
        vbox1 = Gtk.VBox()
        hbox1.pack_end(vbox1, False, False, 0)
        button1 = Gtk.Button()
        button1.set_size_request(40, 40)
        button1.set_tooltip_text(_('Add new folder'))
        button1.set_image(Gtk.Image.new_from_stock(
            Gtk.STOCK_ADD, Gtk.IconSize.BUTTON))
        button1.connect('clicked', self.on_button1_clicked)
        vbox1.pack_start(button1, False, False, 0)
        button2 = Gtk.Button()
        button2.set_size_request(40, 40)
        button2.set_tooltip_text(_('Remove selected folder'))
        button2.set_image(Gtk.Image.new_from_stock(
            Gtk.STOCK_REMOVE, Gtk.IconSize.BUTTON))
        button2.connect('clicked', self.on_button2_clicked)
        vbox1.pack_start(button2, False, False, 0)
        button3 = Gtk.Button()
        button3.set_size_request(40, 40)
        button3.set_tooltip_text(_('Remove all folders'))
        button3.set_image(Gtk.Image.new_from_stock(
            Gtk.STOCK_CLEAR, Gtk.IconSize.BUTTON))
        button3.connect('clicked', self.on_button3_clicked)
        vbox1.pack_end(button3, False, False, 0)
        #
        self.from_filebrowser = from_filebrowser
        if not self.from_filebrowser:
            self.load_preferences()
        #
        self.progreso_dialog = None
        self.files = []
        #
        if len(folders) > 0:
            model = self.treeview.get_model()
            model.clear()
            for folder in folders:
                model.append([True, True, folder])
        #
        self.show_all()

    def on_close_application(self, widget):
        self.save_preferences()
        self.hide()
        self.destroy()

    def toggled_cb(self, cell, path, user_data):
        model, column = user_data
        model[path][column] = not model[path][column]
        self.save_preferences()
        return

    def load_preferences(self):
        configuration = Configuration()
        model = self.treeview.get_model()
        model.clear()
        folders = configuration.get('folders')
        for folder in folders:
            scan = folder['scan']
            recursive = folder['recursive']
            folder_name = folder['name']
            model.append([scan, recursive, folder_name])

    def save_preferences(self):
        if not self.from_filebrowser:
            folders = []
            model = self.treeview.get_model()
            itera = model.get_iter_first()
            while(itera is not None):
                folder = {}
                folder['scan'] = model.get(itera, 0)[0]
                folder['recursive'] = model.get(itera, 1)[0]
                folder['name'] = model.get(itera, 2)[0]
                folders.append(folder)
                itera = model.iter_next(itera)
            if len(folders) > 0:
                configuration = Configuration()
                configuration.set('folders', folders)
                configuration.save()

    def on_button1_clicked(self, widget):
        dialog = Gtk.FileChooserDialog(_(
            'Select Folder...'),
            None,
            Gtk.FileChooserAction.SELECT_FOLDER,
            (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
             Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
        dialog.set_default_response(Gtk.ResponseType.OK)
        response = dialog.run()
        if response == Gtk.ResponseType.OK:
            if not self.exists_folder(dialog.get_filename()):
                model = self.treeview.get_model()
                model.append([True, False, dialog.get_filename()])
        dialog.destroy()

    def exists_folder(self, folder):
        exists = False
        model = self.treeview.get_model()
        itera = model.get_iter_first()
        while(itera is not None):
            value = model.get(itera, 2)[0]
            itera = model.iter_next(itera)
            if value == folder:
                itera = None
                exists = True
        return exists

    def on_button2_clicked(self, widget):
        selected = self.treeview.get_selection()
        model = self.treeview.get_model()
        if selected is not None:
            if selected.get_selected()[1] is not None:
                model.remove(selected.get_selected()[1])

    def on_button3_clicked(self, widget):
        model = self.treeview.get_model()
        model.clear()

    def on_button_scan_home_clicked(self, widget):
        fp = FolderProcessor(ishome=True)
        self.progreso_dialog = Progreso(
            _('Processing folders...'), self, 1)
        self.progreso_dialog.connect(
            'i-want-stop', fp.stop_it)
        fp.connect('to-process', self.on_to_process_folder)
        fp.connect('processed', self.on_processed_folder)
        fp.connect('finished', self.on_processed_folders)
        fp.start()
        self.progreso_dialog.run()

    def on_button_scan_clicked(self, widget):
        model = self.treeview.get_model()
        fp = FolderProcessor(model)
        if self.progreso_dialog is not None:
            self.progreso_dialog.destroy()
            self.progreso_dialog = None
        self.progreso_dialog = Progreso(
            _('Processing folders...'), self, len(model))
        self.progreso_dialog.connect(
            'i-want-stop', fp.stop_it)
        fp.connect('to-process', self.on_to_process_folder)
        fp.connect('processed', self.on_processed_folder)
        fp.connect('finished', self.on_processed_folders)
        fp.start()
        self.progreso_dialog.run()

    def on_to_process_folder(self, processor, afile):
        # GLib.idle_add(self.progreso_dialog.set_scanning_file, afile)
        self.progreso_dialog.set_scanning_file(afile)

    def on_processed_folder(self, processor):
        # GLib.idle_add(self.progreso_dialog.increase)
        self.progreso_dialog.increase()

    def on_processed_folders(self, processor, container):
        files = container.get_data()
        if len(files) > 0:
            scanner = Scanner(self.scanner, files)
            scanner.connect('to-scan', self.going_to_scan)
            scanner.connect('scanned', self.on_progress)
            scanner.connect('infected', self.on_infected_detect)
            scanner.connect('finished', self.on_scan_finished)
            print(2)
            if self.progreso_dialog is not None:
                self.progreso_dialog.destroy()
                self.progreso_dialog = None
            print(3)
            self.progreso_dialog = Progreso(_('Scanning...'), self, len(files))
            print(4)
            self.progreso_dialog.connect(
                'i-want-stop', scanner.stop_it)
            print(5)
            self.infected = []
            print(6)
            scanner.start()
            self.progreso_dialog.run()

    def going_to_scan(self, scanner, afile):
        # GLib.idle_add(self.progreso_dialog.set_scanning_file, afile)
        self.progreso_dialog.set_scanning_file(afile)

    def on_progress(self, scanner):
        # GLib.idle_add(self.progreso_dialog.increase)
        self.progreso_dialog.increase()

    def on_infected_detect(self, scanner, infected):
        self.infected.append(infected)

    def on_scan_finished(self, scanner):
        # GLib.idle_add(self._on_scan_finished)
        if self.progreso_dialog is not None:
            self.progreso_dialog.destroy()
            self.progreso_dialog = None
        md = Gtk.MessageDialog(parent=self)
        md.set_title('Antiviral')
        md.set_property('message_type', Gtk.MessageType.INFO)
        md.add_button(Gtk.STOCK_OK, Gtk.ResponseType.ACCEPT)
        md.set_property('text', _('Antiviral'))
        if len(self.infected) > 0:
            md.format_secondary_text(
                _('What a pity!, In this machine there are viruses!'))
            md.run()
            md.destroy()
            actions = Actions(self, self.infected)
            actions.run()
            actions.destroy()
        else:
            md.format_secondary_text(_('Congratulations!!, no viruses found'))
            md.run()
            md.destroy()

    def on_button_update_clicked(self, widget):
        self.update_database()

    def on_button_about_clicked(self, widget):
        ad = Gtk.AboutDialog()
        ad.set_name(comun.APPNAME)
        ad.set_version(comun.VERSION)
        ad.set_copyright('''
Copyrignt (c) 2010 - 2016
Lorenzo Carbonell Cerezo
''')
        ad.set_comments(_('A graphical interface for\nClamAV'))
        ad.set_license('''
This program is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any later
version.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>.
''')
        ad.set_logo(GdkPixbuf.Pixbuf.new_from_file(comun.ICON))
        ad.set_icon(GdkPixbuf.Pixbuf.new_from_file(comun.ICON))
        ad.set_website('http://www.atareao.es')
        ad.set_website_label('http://www.atareao.es')
        ad.set_authors([
            'Lorenzo Carbonell <*****@*****.**>'])
        ad.set_documenters([
            'Lorenzo Carbonell <*****@*****.**>'])
        ad.set_program_name(_('Antiviral'))
        ad.run()
        ad.hide()
        ad.destroy()

    def update_database(self):
        p = subprocess.Popen([
            'gksu', 'freshclam'], bufsize=10000, stdout=subprocess.PIPE)
        output = p.communicate()[0]  # store stdout
        msg = ''
        print(output)
        for line in output.decode().split('\n'):
            if line.find('main') != -1:
                if line.find('is up to date') != -1:
                    msg = _('main is up to date\n')
                else:
                    msg = _('main updated\n')
            if line.find('daily') != -1:
                if line.find('is up to date') != -1:
                    msg += _('daily is up to date\n')
                else:
                    msg += _('daily updated\n')
            if line.find('bytecode') != -1:
                if line.find('is up to date') != -1:
                    msg += _('bytecode is up to date\n')
                else:
                    msg += _('bytecode updated\n')
        if msg == '':
            msg = output
            tipo = Gtk.MessageType.ERROR
            md = Gtk.MessageDialog(self, 0, tipo, Gtk.ButtonsType.CLOSE, msg)
            md.set_title('Antiviral')
            md.run()
            md.destroy()
        else:
            tipo = Gtk.MessageType.INFO
            msg += '\n\n'+_('Reloading')+'...'
            md = Gtk.MessageDialog(self, 0, tipo, Gtk.ButtonsType.CLOSE, msg)
            md.set_title('Antiviral')
            md.run()
            md.destroy()
            print(self.scanner.reload())