An (outdated) collection of plugins for Qtile.
git clone https://github.com/m-col/qtools
Files | Refs | Readme

-rw-r--r-- qtools/rofi_searx/searx.py


      1 """
      2 Qtile plugin to use rofi to execute a process using the URL for a randomised searx
      3 instance.
      4 
      5 Example usage:
      6 
      7     import qtools.rofi_searx
      8     searx = qtools.rofi_searx.Searx()
      9     keys.extend([EzKey(k, v) for k, v in {
     10         'M-s':   searx.lazy_search,
     11         'M-C-s': searx.lazy_remove_last_used,
     12     }.items()])
     13 
     14 """
     15 
     16 
     17 import random
     18 import shlex
     19 import subprocess
     20 
     21 from qtools import Notifier
     22 
     23 
     24 class Searx(Notifier):
     25     """
     26     This plugin opens a rofi prompt to get a search query from the user, then randomly
     27     selects a searx instance from a provided list and opens a browser to carry out the
     28     web search.
     29 
     30     Searx instances can be provided directly as a list, or alternatively an
     31     instances_file path can be provided to load the list of searx instances from a file
     32     containing line-separated full URLs to searx instances.
     33 
     34     Searx.remove_last_used can be used to remove the previously used searx instance from
     35     the instance list. If an instance_file was provided, the last instance will simply
     36     be commented out in the file and ignored, but not removed. New instances can be
     37     added by adding to the file, and either restarting Qtile or binding
     38     Searx.lazy_load_instances to a key.
     39     """
     40     defaults = [
     41         ('summary', 'Searx', 'Notification summary.'),
     42         ('instances', ['https://searx.me'], 'List of searx instance base URLs.'),
     43         ('instances_file', None, 'File containing list of searx instances. If specified'
     44                                  ' instances passed directly are ignored.'),
     45         ('prompt', 'Search the web', 'Prompt displayed by rofi.'),
     46         ('theme', None, 'rofi theme to use.'),
     47         ('launcher', 'tor-browser --allow-remote {url}', 'Command used to open web '
     48                                                          'browser. Requires {url} to '
     49                                                          'place the search url.'),
     50         ('notify_on_remove', True, 'Whether to make a notification when removing a '
     51                                    'searx instance.'),
     52     ]
     53 
     54     def __init__(self, **config):
     55         Notifier.__init__(self, **config)
     56         self.add_defaults(Searx.defaults)
     57         self.last_used = None
     58 
     59         self.command = ['rofi', '-dmenu', '-l', '0']
     60         if self.prompt:
     61             self.command.extend(['-p', self.prompt])
     62         if self.theme:
     63             self.command.extend(['-theme', self.theme])
     64 
     65         if self.instances_file:
     66             self.load_instances()
     67 
     68     def search(self, qtile=None):
     69         output = subprocess.run(
     70             self.command, stdout=subprocess.PIPE, universal_newlines=True, check=False
     71         )
     72         if output.stdout and not output.returncode:
     73             if self.instances_file:
     74                 instance = random.choice(
     75                     [i for i in self.instances if not i.startswith('#')]
     76                 )
     77             else:
     78                 instance = random.choice(self.instances)
     79 
     80             query = output.stdout.strip()
     81             url = f"'{instance}/?q={query}&categories=general&language=en-US'"
     82             command = self.launcher.format(url=url)
     83             subprocess.Popen(shlex.split(command))
     84             self.last_used = instance
     85 
     86     def remove_last_used(self, qtile=None):
     87         if self.last_used:
     88             self.instances.remove(self.last_used)
     89             if self.instances_file:
     90                 self.instances.append(f'#{self.last_used}')
     91                 self.save_instances()
     92             if self.notify_on_remove:
     93                 self.show(f'Removed: {self.last_used}')
     94             self.last_used = None
     95 
     96     def load_instances(self, qtile=None):
     97         with open(self.instances_file, 'r') as f:
     98             self.instances = f.read().split()
     99 
    100     def save_instances(self):
    101         with open(self.instances_file, 'w') as f:
    102             f.write('\n'.join(self.instances))
    103