Posted in: Ubuntu

GNOME Shell 3.4 Extension that will add remmina configurations to the search results

Posted on June 27, 2012 by Michael Roma

Below is javascript code for a gnome shell 3.4 extension that will add remmina configurations that are stored in a text file to the shell search results. I plan to update this extension in the future to read the contents .remmina directory instead of a text file. The text file is assumed to be ~/src/rdp and contain an rdp per line in the format: Server 1{tab}12312323.remmina Server 2{tab}23444324.remmina etc.

const St = imports.gi.St;
const Main = imports.ui.main;
const Search = imports.ui.search;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const Util = imports.misc.util;

// define search provider object
var rdpSearchProvider = null;

// define file watch to detect changes in the source text file
var rdpConfigFileWatcher = null;

// define class
const RemminaSearchProvider = new Lang.Class({
    Name: 'RemminaSearchProvider',
    Extends: Search.SearchProvider,

    // init
    _init: function(name) {
        global.log('init remmina-search');
        Search.SearchProvider.prototype._init.call(this, "Remote Desktops");


        // define remmina path 
        this.remminaPath = GLib.build_filenamev([GLib.get_home_dir(), ".remmina"]);
        
        // define config path for remmina definitions
        this.remminaConfigPath = GLib.build_filenamev([GLib.get_home_dir(), "src/rdp"]);
                                     
      
        // define the remmina config list and read
        this._remminaConfigs = [];
        this._readRemminaConfigs();

        // setup file monitor to detect changes
        let fileWatch = Gio.file_new_for_path(this.remminaConfigPath);
        rdpConfigFileWatcher = fileWatch.monitor(Gio.FileMonitorFlags.NONE, null);
        rdpConfigFileWatcher.connect('changed', Lang.bind(this, this._readRemminaConfigs));       

        return true;
    },
    

    // function that reads the configurations from the file
    _readRemminaConfigs : function () {

        // init list
        this._remminaConfigs = [];
        
        // get the file data
        let filedata;
        try {
            filedata = GLib.file_get_contents(this.remminaConfigPath, null, 0);
        } catch (e) {
            Main.notifyError("Error reading file", e.message);
            return false;
        }


        // attempt to parse the data        
        if ( (filedata[1].length != 0) && (filedata[1] != null) ) {
            try {
                
                // get each line
                let rdpInfoLines = String(filedata[1]).trim().split('\n');                
                for (var i=0; i<rdpInfoLines.length; i++) {                

                    // parse rdp info: 0 = name, 1 = remmina config file
                    let rdpInfo = String(rdpInfoLines[i]).trim().split('\t');
                    
                    // push rdp info to the list
                    this._remminaConfigs.push([rdpInfo[0], this.remminaPath + "/" + rdpInfo[1]]);                    
                }                
                
            } catch (e) {
                Main.notifyError("Error parsing file - "+ filedata, e.message);
                return false;
            }
        } else {
            Main.notifyError("Error parsing file - Empty data");
            return false;
        }
        
        // ok
        return true;
    },
    
    
    // return results back to search
    getResultMetas: function(resultIds, callback) {

        // define results
        let metas = [];

        // go through each result
        for (let i = 0; i < resultIds.length; i++) {            
            let resultId = resultIds[i];

            // get the rdp name, fallback to url if no name
            let rdpInfoName = "";
            if (resultId.name)
                rdpInfoName = resultId.name;
            else
                rdpInfoName = resultId.url;

            // add the result to the list
            metas.push({ 'id': resultId,
                     'name': rdpInfoName,
                     'createIcon': function(size) {
                            let xicon = new Gio.ThemedIcon({name: 'remmina'});
                            return new St.Icon({icon_size: size, gicon: xicon});
                    }
            });
        }
        
        // call back with results
        callback(metas);
    },

    // define method to open fetched result
    activateResult: function(id) {
        Util.spawn(['/usr/bin/remmina', '-c', id.url]);
    },

    // function that searches the rdp configs using terms passed 
    _checkRemminaConfigs: function(configs, terms) {

        // define results
        let searchResults = [];

        // go through each rdp and term
        for (var i=0; i<configs.length; i++) {
            for (var j=0; j<terms.length; j++) {

                try {
                    // get the name and url and build the string to search
                    let name = configs[i][0];
                    let url = configs[i][1];
                    let searchStr = name+url;

                    // search the string
                    let pattern = new RegExp(terms[j],"gi");
                    if (searchStr.match(pattern)) {

                        // add to the list if matched
                        searchResults.push({
                                'name': name,
                                'url': url
                        });
                    }
                }
                catch(ex) {
                    continue;
                }
            }
        }

        // return results
        return searchResults;
    },

    // function that returns the initial results
    getInitialResultSet: function(terms) {
        this.searchSystem.pushResults(this, this._checkRemminaConfigs(this._remminaConfigs, terms));    
    },

    // call same initial search on subsearch
    getSubsearchResultSet: function(previousResults, terms) {
        this.getInitialResultSet(terms);
    }
});


// init event
function init(meta) {
}

// enable event
function enable() {

    // check if search provider already initialized, create new
    if (rdpSearchProvider==null) {
        rdpSearchProvider = new RemminaSearchProvider();
        Main.overview.addSearchProvider(rdpSearchProvider);
    }
}

// disable event
function disable() {

    // if search provider exists, disable it
    if  (rdpSearchProvider!=null) {
        Main.overview.removeSearchProvider(rdpSearchProvider);
        rdpSearchProvider.rdpConfigFileWatcher.cancel(); 
        rdpSearchProvider = null;
    }
}

Cardapio plugin to search Remmina configurations

Posted on October 22, 2011 by Michael Roma

Cardapio plugin to search Remmina configurations written in python:



You may need to update the path for Remmina configurations, on line 51 below.

#  
#  Copyright (C) 2011 mroma (mroma82@gmail.com)
# 

class CardapioPlugin (CardapioPluginInterface):

    author             = 'mroma' 
    name               = _('Remmina')
    description        = _('Searches remmina connections')

    url                = ''
    help_text          = ''
    version            = '0.02'

    plugin_api_version = 1.40

    search_delay_type  = None

    default_keyword    = 'run'

    category_name      = _('Remmina')
    category_icon      = 'remmina'
    icon               = 'remmina'
    category_tooltip   = _('Searches remmina connections')

    fallback_icon      = 'system-run'

    hide_from_sidebar  = False         

    # init
    def __init__(self, cardapio_proxy, category):
        '''    
        This method is called when the plugin is enabled.
        Nothing much to be done here except initialize variables and set loaded to True
        '''
        self.c = cardapio_proxy
        
        try:
            import os            

        except Exception, exception:
            self.c.write_to_log(self, 'Could not import certain modules', is_error = True)
            self.c.write_to_log(self, exception, is_error = True)
            self.loaded = False
            return

        self.os    = os
               
        
        # get the directory for remmina configs
        self.dirname = os.getenv("HOME") + "/.remmina/"
        
        """ 
            build a list of tuples with (name, filename) 
        """
        # init the list
        self.list = []
        
        # go through  file
        for f in os.listdir(self.dirname):
            # make sure a .remmina file                                       
            if f.endswith(".remmina"):
                
                # go through each line
                lines = open(os.path.join(self.dirname, f), 'r').readlines()
                for line in lines:
                    
                    # check if the name line, if so, add to the list
                    if line.startswith("name="):                    
                        self.list.append((line[5:255].rstrip('\n'), f));

        # sort the list, by name
        self.list.sort()   
        
        self.loaded = True # set to true if everything goes well


    # search
    def search(self, text, result_limit):

        # save the search test
        self.current_query = text
        
        # search through the list of remmina configurations
        my_items = []
        if self.list and text:        
            for (name, file) in self.list:                       
            
                # check if the configuration name contains the search text
                if name.lower().find(text.lower()) != -1:    
                
                    # add the item
                    item = {
                        'name' : name,
                        'tooltip' : 'remmina -c ' + self.dirname + file,
                        'icon name' : 'remmina',
                        'type' : 'raw-no-notification',
                        'command' : 'remmina -c ' + self.dirname + file,
                        'context menu' : None
                        }  
                    my_items.append(item)
                                                
        # show the results                                                          
        self.c.handle_search_result(self, my_items, self.current_query)

Download remmina.py