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

file_status: allow several paths, new format #1369

Merged
merged 21 commits into from
Jul 5, 2018
Merged
Changes from 7 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
74 changes: 61 additions & 13 deletions py3status/modules/file_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,46 @@

Configuration parameters:
cache_timeout: how often to run the check (default 10)
format: format of the output. (default '{icon}')
format: format of the output. (default '{icon} {format_path}')
format_path: format of the path output. (default '{basename}')
format_path_separator: show separator if more than one (default ' ')
icon_available: icon to display when available (default '●')
icon_unavailable: icon to display when unavailable (default '■')
path: the path to a file or dir to check if it exists (default None)
path: the path(s) to a file or dir to check if it exists, take a list (default None)
Copy link
Contributor

@lasers lasers Jun 19, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Too long imo. path: specify a string or a list of paths to check (default None)


Color options:
color_bad: Error or file/directory does not exist
color_good: File or directory exists

Format placeholders:
{format_path} paths of matching files
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is missing a {paths} placeholder, eg..

    {paths} number of paths, eg 1, 2, 3
    {format_path} format for paths

{icon} icon for the current availability

@author obb, Moritz Lüdecke
format_path path placeholders:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

format_path path placeholders:

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick :)

{basename} basename of matching files
{fullpath} fullpath of matching files

Examples:
```
# check files with wildcard, or contain user path, full paths
file_status {
path = ['/tmp/test*', '~user/test1']
format_path = '{fullpath}'
}
```

@author obb, Moritz Lüdecke, Cyril Levis (@cyrinux)

SAMPLE OUTPUT
{'color': '#00FF00', 'full_text': u'\u25cf'}
{'color': '#00FF00', 'full_text': u'\u25cf test.py'}

missing
{'color': '#FF0000', 'full_text': u'\u25a0'}
"""

from os.path import expanduser, exists
from glob import glob
from itertools import chain
from os.path import basename, expanduser

ERR_NO_PATH = 'no path given'

Expand All @@ -35,7 +53,9 @@ class Py3status:
"""
# available configuration parameters
cache_timeout = 10
format = '{icon}'
format = u'{icon} {format_path}'
format_path = u'{basename}'
format_path_separator = u' '
icon_available = u'●'
icon_unavailable = u'■'
path = None
Expand All @@ -58,7 +78,11 @@ class Meta:

def post_config_hook(self):
if self.path:
self.path = expanduser(self.path)
# backward compatibility, str to list
if not isinstance(self.path, list):
self.path = [self.path]
# expand user paths
self.path = list(map(expanduser, self.path))

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keep this so we can do expanduser(path) once instead of every refresh interval.

Copy link
Contributor Author

@cyrinux cyrinux Jun 12, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had a doubt about this, refresh is for example when I py3-cmd resfresh file_status? I thought this part was only excecuted at the py3status start/restart.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not understand this sorry, could you rephrase? "I'd clear this with the fam first."

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have a discussion with tobes and/or ultrabug. They our fam.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh sorry, fam = familly >_>

def file_status(self):
if self.path is None:
Expand All @@ -68,16 +92,40 @@ def file_status(self):
'cached_until': self.py3.CACHE_FOREVER,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should move this to post_config_hook too. See hamster for an example.

Copy link
Contributor Author

@cyrinux cyrinux Jun 19, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hamster from which branch? :)

Copy link
Contributor

@lasers lasers Jun 19, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Master Splinter! Or see weather_yahoo.. or to be more specific, do like this...

STRING_NO_PATH = 'missing path'
    def post_config_hook(self):
        if not self.path:
            raise Exception(STRING_NO_PATH)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ha ok I was far away

}

if exists(self.path):
icon = self.icon_available
# init data
file_status_data = {}
# expand glob from paths
paths = list(map(glob, self.path))
# merge list of paths
paths = [x for x in chain.from_iterable(paths)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if it is more efficient to += the list instead of using chain and map.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Idk

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try paths = sorted([files for path in self.path for files in glob(path)])

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dont know if this is better but it works :) not used to read this :|


# fill data
file_status_data['icon'] = self.icon_unavailable
color = self.py3.COLOR_BAD

if paths:
file_status_data['icon'] = self.icon_available
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, I really would like to deprecate icon in favor of a files (like message/messages) so the format could look like this... format = '\?if=files ●|■' instead... And {files} would be a number of files.

I guess we stick with just allow several path and not rewriting this from scratch. lol.

Just mentioning that file_status will pick up directories too with wildcard. Anyhow, keep it as-is.

Copy link
Contributor Author

@cyrinux cyrinux Jun 18, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So i remove legacy stuff? Or I just add files, and we can remove {icon} from config and use new format.

Copy link
Contributor

@lasers lasers Jun 18, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally, we do no more than to allow several path PR. We definitely can add (count) {paths} for format because it is still related.

It'd be good to ask the fam first about deprecating {icon} as this would allow us to get rid of icon_available and icon_unavailable in favor of format = '\?if=paths ●|■'. Also, ask about the new {format_path} in default format (versus) just icons. I think it's better than icons too. Maybe not...

color = self.py3.COLOR_GOOD
else:
icon = self.icon_unavailable
color = self.py3.COLOR_BAD
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There sure are lot of changes. We might as well see this all the way to finish... by removing colors, make and default thresholds with 0, 1. With glob and several paths implemented, we might want thresholds anyway as it would enhance this module... allowing us to print colors based on number of paths somewhere.

This module is useful now because I can use this to print names of custom modules... and globbing. Thank you for working on this. :-)


# format paths
if self.format_path:
format_path = {}

format_path_separator = self.py3.safe_format(
self.format_path_separator)

format_path['basename'] = self.py3.composite_join(
format_path_separator, map(basename, paths))

format_path['full'] = self.py3.composite_join(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Due to glob, there can be many things in the list. We could be a bit more efficient by using get_placeholders_list-in-post_config_hook list for format_path and find out which placeholder we want to join... rather than always joining them both.

Look composite_join in composite.py. It makes a composite obj, go thru list, append separator, append item, etc... which could always be skipped on every interval instead. This is an optional nit.

format_path_separator, paths)

file_status_data['format_path'] = self.py3.safe_format(
self.format_path, format_path)

response = {
'cached_until': self.py3.time_in(self.cache_timeout),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cache_timeout = -1 in your example means once. You may want cache_timeout = 0 instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my example I use py3-cmd refresh file_status for try ;)

'full_text': self.py3.safe_format(self.format, {'icon': icon}),
'full_text': self.py3.safe_format(self.format, file_status_data),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Opinion). May look cleaner if we pass paths and format_path here like the icon.

'color': color
}

Expand Down