Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New buffer "directories" #1567

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion alot/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@


_SUBCOMMANDS = ['search', 'compose', 'bufferlist', 'taglist', 'namedqueries',
'pyshell']
'pyshell', 'directories']


def parser():
Expand Down
1 change: 1 addition & 0 deletions alot/buffers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@
from .taglist import TagListBuffer
from .thread import ThreadBuffer
from .namedqueries import NamedQueriesBuffer
from .directories import DirectoriesBuffer
78 changes: 78 additions & 0 deletions alot/buffers/directories.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Copyright (C) 2011-2018 Patrick Totzke <[email protected]>
# This file is released under the GNU GPL, version 3 or a later revision.
# For further details see the COPYING file
import urwid

from .buffer import Buffer
from ..settings.const import settings
from ..widgets.directories import DirectorylineWidget


class DirectoriesBuffer(Buffer):
"""lists directories in all Maildirs present in the notmuch database"""

modename = 'directories'

def __init__(self, ui, filtfun):
self.ui = ui
self.filtfun = filtfun
self.isinitialized = False
self.querylist = None
self.rebuild()
Buffer.__init__(self, ui, self.body)

def rebuild(self):
self.queries = self.ui.dbman.get_directory_queries()

if self.isinitialized:
focusposition = self.querylist.get_focus()[1]
else:
focusposition = 0

lines = []
for (num, key) in enumerate(self.queries):
value = self.queries[key]
count = self.ui.dbman.count_messages('%s' % value)
count_unread = self.ui.dbman.count_messages('%s and '
'tag:unread' % value)
line = DirectorylineWidget(key, value, count, count_unread)

if (num % 2) == 0:
attr = settings.get_theming_attribute('directories',
'line_even')
else:
attr = settings.get_theming_attribute('directories',
'line_odd')
focus_att = settings.get_theming_attribute('directories',
'line_focus')

line = urwid.AttrMap(line, attr, focus_att)
lines.append(line)

self.querylist = urwid.ListBox(urwid.SimpleListWalker(lines))
self.body = self.querylist

self.querylist.set_focus(focusposition % len(self.queries))

self.isinitialized = True

def focus_first(self):
"""Focus the first line in the query list."""
self.body.set_focus(0)

def focus_last(self):
allpos = self.querylist.body.positions(reverse=True)
if allpos:
lastpos = allpos[0]
self.body.set_focus(lastpos)

def get_selected_query(self):
"""returns selected query"""
return self.querylist.get_focus()[0].original_widget.query

def get_info(self):
info = {}

info['query_count'] = len(self.queries)

return info
1 change: 1 addition & 0 deletions alot/commands/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class SequenceCanceled(Exception):
'bufferlist': {},
'taglist': {},
'namedqueries': {},
'directories': {},
'thread': {},
'global': {},
}
Expand Down
29 changes: 29 additions & 0 deletions alot/commands/directories.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Copyright (C) 2011-2018 Patrick Totzke <[email protected]>
# This file is released under the GNU GPL, version 3 or a later revision.
# For further details see the COPYING file
import argparse

from . import Command, registerCommand
from .globals import SearchCommand

MODE = 'directories'


@registerCommand(MODE, 'select', arguments=[
(['filt'], {'nargs': argparse.REMAINDER,
'help': 'additional filter to apply to query'}),
])
class DirectoriesSelectCommand(Command):

"""search for messages with selected query"""
def __init__(self, filt=None, **kwargs):
self._filt = filt
Command.__init__(self, **kwargs)

async def apply(self, ui):
query = [ui.current_buffer.get_selected_query()]
if self._filt:
query.extend(['and'] + self._filt)

cmd = SearchCommand(query=query)
await ui.apply_command(cmd)
13 changes: 13 additions & 0 deletions alot/commands/globals.py
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,19 @@ def __init__(self, filtfun=bool, **kwargs):
def apply(self, ui):
ui.buffer_open(buffers.NamedQueriesBuffer(ui, self.filtfun))

@registerCommand(MODE, 'directories')
class DirectoriesCommand(Command):
"""opens directories buffer"""
def __init__(self, filtfun=bool, **kwargs):
"""
:param filtfun: filter to apply to displayed list
:type filtfun: callable (str->bool)
"""
self.filtfun = filtfun
Command.__init__(self, **kwargs)

def apply(self, ui):
ui.buffer_open(buffers.DirectoriesBuffer(ui, self.filtfun))

@registerCommand(MODE, 'flush')
class FlushCommand(Command):
Expand Down
17 changes: 17 additions & 0 deletions alot/db/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from collections import deque
import contextlib
import logging
import os

from notmuch2 import Database, NotmuchError, XapianError
import notmuch2
Expand Down Expand Up @@ -296,6 +297,22 @@ def get_named_queries(self):
return {k[6:]: db.config[k] for k in db.config if
k.startswith('query.')}

def get_directory_queries(self):
"""
returns the directory structure in the database.
:rtype: dict (str -> str) mapping alias to full query string
"""
queries = {};
for root, dirs, files in os.walk(self.path):
dirs[:] = [d for d in dirs if not (d[0] == '.'
or d in ('new','cur','tmp'))]
subpath = root[len(self.path):]
if not subpath:
queries['/'] = 'path:"**"'
else:
queries['/'+subpath] = 'path:"'+subpath+'/**"'
return queries

def get_threads(self, querystring, sort='newest_first', exclude_tags=None):
"""
asynchronously look up thread ids matching `querystring`.
Expand Down
6 changes: 6 additions & 0 deletions alot/defaults/alot.rc.spec
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,12 @@ taglist_statusbar = mixed_list(string, string, default=list('[{buffer_no}: tagli
# that will be substituted accordingly.
namedqueries_statusbar = mixed_list(string, string, default=list('[{buffer_no}: namedqueries]','{query_count} named queries'))

# Format of the status-bar in directory list mode.
# This is a pair of strings to be left and right aligned in the status-bar.
# These strings may contain variables listed at :ref:`bufferlist_statusbar <bufferlist-statusbar>`
# that will be substituted accordingly.
directories_statusbar = mixed_list(string, string, default=list('[{buffer_no}: directories]','{query_count} directories'))

# Format of the status-bar in envelope mode.
# This is a pair of strings to be left and right aligned in the status-bar.
# Apart from the global variables listed at :ref:`bufferlist_statusbar <bufferlist-statusbar>`
Expand Down
3 changes: 3 additions & 0 deletions alot/defaults/default.bindings
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ q = exit
[namedqueries]
enter = select

[directories]
enter = select

[thread]
enter = select
C = fold *
Expand Down
4 changes: 4 additions & 0 deletions alot/defaults/default.theme
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@
line_focus = 'standout','','yellow','light gray','#ff8','g58'
line_even = 'default','','light gray','black','default','g3'
line_odd = 'default','','light gray','black','default','default'
[directories]
line_focus = 'standout','','yellow','light gray','#ff8','g58'
line_even = 'default','','light gray','black','default','g3'
line_odd = 'default','','light gray','black','default','default'
[thread]
arrow_heads = '','','dark red','','#a00',''
arrow_bars = '','','dark red','','#800',''
Expand Down
4 changes: 4 additions & 0 deletions alot/defaults/theme.spec
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@
line_focus = attrtriple
line_even = attrtriple
line_odd = attrtriple
[directories]
line_focus = attrtriple
line_even = attrtriple
line_odd = attrtriple
[search]
[[threadline]]
normal = attrtriple
Expand Down
30 changes: 30 additions & 0 deletions alot/widgets/directories.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Copyright (C) 2011-2018 Patrick Totzke <[email protected]>
# This file is released under the GNU GPL, version 3 or a later revision.
# For further details see the COPYING file

"""
Widgets specific to directories mode
"""
import urwid


class DirectorylineWidget(urwid.Columns):
def __init__(self, key, value, count, count_unread):
self.query = value

count_widget = urwid.Text('{0:>7} {1:7}'.
format(count, '({0})'.format(count_unread)))
key_widget = urwid.Text(key)
value_widget = urwid.Text(value)

urwid.Columns.__init__(self, (key_widget, count_widget, value_widget),
dividechars=1)

def selectable(self):
return True

def keypress(self, size, key):
return key

def get_query(self):
return self.query
4 changes: 4 additions & 0 deletions extra/themes/mutt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
line_even = '','','light gray','black','light gray','black'
line_odd = '','','light gray','black','light gray','black'
line_focus = 'standout','','black','dark cyan','black','dark cyan'
[directories]
line_even = '','','light gray','black','light gray','black'
line_odd = '','','light gray','black','light gray','black'
line_focus = 'standout','','black','dark cyan','black','dark cyan'
[taglist]
line_even = '','','light gray','black','light gray','black'
line_odd = '','','light gray','black','light gray','black'
Expand Down
4 changes: 4 additions & 0 deletions extra/themes/solarized_dark
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ green = 'dark green'
line_even = 'default','default','%(base0)s','%(base02)s','%(base0)s','%(base02)s'
line_focus = 'standout','default','%(base1)s','%(base01)s','%(base1)s','%(base01)s'
line_odd = 'default','default','%(base0)s','%(base03)s','%(base0)s','%(base03)s'
[directories]
line_even = 'default','default','%(base0)s','%(base02)s','%(base0)s','%(base02)s'
line_focus = 'standout','default','%(base1)s','%(base01)s','%(base1)s','%(base01)s'
line_odd = 'default','default','%(base0)s','%(base03)s','%(base0)s','%(base03)s'
[taglist]
line_even = 'default','default','%(base0)s','%(base02)s','%(base0)s','%(base02)s'
line_focus = 'standout','default','%(base1)s','%(base01)s','%(base1)s','%(base01)s'
Expand Down
4 changes: 4 additions & 0 deletions extra/themes/solarized_light
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@
line_focus = 'standout','default','%(16_base2)s','%(16_yellow)s','%(256_base2)s','%(256_yellow)s'
line_even = 'default','default','%(16_base00)s','%(16_base3)s','%(256_base00)s','%(256_base3)s'
line_odd = 'default','default','%(16_base00)s','%(16_base2)s','%(256_base00)s','%(256_base2)s'
[directories]
line_focus = 'standout','default','%(16_base2)s','%(16_yellow)s','%(256_base2)s','%(256_yellow)s'
line_even = 'default','default','%(16_base00)s','%(16_base3)s','%(256_base00)s','%(256_base3)s'
line_odd = 'default','default','%(16_base00)s','%(16_base2)s','%(256_base00)s','%(256_base2)s'
[taglist]
line_focus = 'standout','default','%(16_base2)s','%(16_yellow)s','%(256_base2)s','%(256_yellow)s'
line_even = 'default','default','%(16_base00)s','%(16_base3)s','%(256_base00)s','%(256_base3)s'
Expand Down
4 changes: 4 additions & 0 deletions extra/themes/sup
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
line_even = '','','light gray','black','light gray','g0'
line_odd = '','','light gray','black','light gray','g0'
line_focus = 'standout','','black','dark cyan','black','dark cyan'
[directories]
line_even = '','','light gray','black','light gray','g0'
line_odd = '','','light gray','black','light gray','g0'
line_focus = 'standout','','black','dark cyan','black','dark cyan'
[taglist]
line_even = '','','light gray','black','light gray','g0'
line_odd = '','','light gray','black','light gray','g0'
Expand Down
4 changes: 4 additions & 0 deletions extra/themes/tomorrow
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ error = 'dark red'
line_focus = 'standout','default','%(16_focus_fg)s','%(16_focus_bg)s','%(256_focus_fg)s','%(256_focus_bg)s'
line_even = 'default','default','%(16_text_fg)s','%(16_normal_bg)s','%(256_text_fg)s','%(256_normal_bg)s'
line_odd = 'default','default','%(16_text_fg)s','%(16_normal_bg)s','%(256_text_fg)s','%(256_normal_bg)s'
[directories]
line_focus = 'standout','default','%(16_focus_fg)s','%(16_focus_bg)s','%(256_focus_fg)s','%(256_focus_bg)s'
line_even = 'default','default','%(16_text_fg)s','%(16_normal_bg)s','%(256_text_fg)s','%(256_normal_bg)s'
line_odd = 'default','default','%(16_text_fg)s','%(16_normal_bg)s','%(256_text_fg)s','%(256_normal_bg)s'
[taglist]
line_focus = 'standout','default','%(16_focus_fg)s','%(16_focus_bg)s','%(256_focus_fg)s','%(256_focus_bg)s'
line_even = 'default','default','%(16_text_fg)s','%(16_normal_bg)s','%(256_text_fg)s','%(256_normal_bg)s'
Expand Down
4 changes: 4 additions & 0 deletions tests/settings/test_theme.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@
line_even = '', '', '', '', '', ''
line_focus = '', '', '', '', '', ''
line_odd = '', '', '', '', '', ''
[directories]
line_even = '', '', '', '', '', ''
line_focus = '', '', '', '', '', ''
line_odd = '', '', '', '', '', ''
[search]
focus = '', '', '', '', '', ''
normal = '', '', '', '', '', ''
Expand Down