| 
									
										
										
										
											2010-12-02 16:46:23 +00:00
										 |  |  | #!/usr/bin/env python | 
					
						
							| 
									
										
										
										
											2012-05-07 06:50:40 +00:00
										 |  |  | # -*- coding: utf-8 -*- | 
					
						
							| 
									
										
										
										
											2012-05-07 06:19:19 +00:00
										 |  |  | """ | 
					
						
							|  |  |  |   Copyright © 2008-2012 Joel Schaerer | 
					
						
							| 
									
										
										
										
											2013-07-07 02:17:54 +00:00
										 |  |  |   Copyright © 2012-2013 William Ting | 
					
						
							| 
									
										
										
										
											2012-05-07 06:19:19 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   *  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, 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, write to the Free Software | 
					
						
							|  |  |  |   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							|  |  |  | """ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-24 09:30:01 +00:00
										 |  |  | from __future__ import division, print_function | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  | from collections import namedtuple | 
					
						
							|  |  |  | from functools import partial | 
					
						
							|  |  |  | from itertools import ifilter | 
					
						
							|  |  |  | from itertools import imap | 
					
						
							|  |  |  | from math import sqrt | 
					
						
							|  |  |  | from operator import attrgetter | 
					
						
							|  |  |  | from operator import itemgetter | 
					
						
							| 
									
										
										
										
											2013-05-14 22:34:19 +00:00
										 |  |  | import os | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  | import platform | 
					
						
							| 
									
										
										
										
											2013-12-17 16:06:13 +00:00
										 |  |  | import re | 
					
						
							| 
									
										
										
										
											2013-05-14 22:34:19 +00:00
										 |  |  | import sys | 
					
						
							| 
									
										
										
										
											2011-09-06 14:21:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  | from argparse import ArgumentParser | 
					
						
							| 
									
										
										
										
											2013-09-26 20:40:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  | from data import load | 
					
						
							|  |  |  | from data import save | 
					
						
							|  |  |  | from utils import decode | 
					
						
							|  |  |  | from utils import encode_local | 
					
						
							|  |  |  | from utils import first | 
					
						
							| 
									
										
										
										
											2013-12-17 16:35:43 +00:00
										 |  |  | from utils import has_uppercase | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  | from utils import is_osx | 
					
						
							|  |  |  | from utils import print_entry | 
					
						
							| 
									
										
										
										
											2013-12-17 16:54:55 +00:00
										 |  |  | from utils import second | 
					
						
							| 
									
										
										
										
											2013-05-21 14:28:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  | VERSION = 'release-v21.8.0' | 
					
						
							|  |  |  | Entry = namedtuple('Entry', ['path', 'weight']) | 
					
						
							| 
									
										
										
										
											2013-09-26 20:40:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-07 01:23:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-14 22:34:19 +00:00
										 |  |  | def set_defaults(): | 
					
						
							|  |  |  |     config = {} | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  |     config['tab_menu_separator'] = '__' | 
					
						
							| 
									
										
										
										
											2012-05-06 23:12:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  |     if is_osx(): | 
					
						
							|  |  |  |         data_home = os.path.join( | 
					
						
							|  |  |  |                         os.path.expanduser('~'), | 
					
						
							|  |  |  |                         'Library', | 
					
						
							|  |  |  |                         'autojump') | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         data_home = os.getenv( | 
					
						
							|  |  |  |                 'XDG_DATA_HOME', | 
					
						
							|  |  |  |                 os.path.join( | 
					
						
							|  |  |  |                         os.path.expanduser('~'), | 
					
						
							|  |  |  |                         '.local', | 
					
						
							|  |  |  |                         'share', | 
					
						
							|  |  |  |                         'autojump')) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     config['data_path'] = os.path.join(data_home, 'autojump.txt') | 
					
						
							|  |  |  |     config['backup_path'] = os.path.join(data_home, 'autojump.txt.bak') | 
					
						
							|  |  |  |     config['tmp_path'] = os.path.join(data_home, 'data.tmp') | 
					
						
							| 
									
										
										
										
											2013-05-14 22:34:19 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return config | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-17 18:03:57 +00:00
										 |  |  | def parse_environment(config): | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  |     # TODO(ting|2013-12-16): add autojump_data_dir support | 
					
						
							|  |  |  |     # TODO(ting|2013-12-15): add ignore case / smartcase support | 
					
						
							|  |  |  |     # TODO(ting|2013-12-15): add symlink support | 
					
						
							| 
									
										
										
										
											2013-05-14 22:34:19 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return config | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-17 18:03:57 +00:00
										 |  |  | def eval_arguments(config): | 
					
						
							|  |  |  |     """Evaluate arguments and run appropriate logic, returning an error code.""" | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  |     parser = ArgumentParser( | 
					
						
							| 
									
										
										
										
											2013-05-15 01:58:24 +00:00
										 |  |  |             description='Automatically jump to directory passed as an argument.', | 
					
						
							| 
									
										
										
										
											2012-05-06 23:41:00 +00:00
										 |  |  |             epilog="Please see autojump(1) man pages for full documentation.") | 
					
						
							| 
									
										
										
										
											2013-02-25 05:49:45 +00:00
										 |  |  |     parser.add_argument( | 
					
						
							| 
									
										
										
										
											2013-02-25 05:55:29 +00:00
										 |  |  |             'directory', metavar='DIRECTORY', nargs='*', default='', | 
					
						
							| 
									
										
										
										
											2012-05-06 23:41:00 +00:00
										 |  |  |             help='directory to jump to') | 
					
						
							| 
									
										
										
										
											2013-02-25 05:49:45 +00:00
										 |  |  |     parser.add_argument( | 
					
						
							| 
									
										
										
										
											2013-05-15 00:03:08 +00:00
										 |  |  |             '-a', '--add', metavar='DIRECTORY', | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  |             help='add path') | 
					
						
							| 
									
										
										
										
											2013-05-15 00:03:08 +00:00
										 |  |  |     parser.add_argument( | 
					
						
							|  |  |  |             '-i', '--increase', metavar='WEIGHT', nargs='?', type=int, | 
					
						
							|  |  |  |             const=20, default=False, | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  |             help='increase current directory weight') | 
					
						
							| 
									
										
										
										
											2013-02-25 05:49:45 +00:00
										 |  |  |     parser.add_argument( | 
					
						
							| 
									
										
										
										
											2013-02-25 05:55:29 +00:00
										 |  |  |             '-d', '--decrease', metavar='WEIGHT', nargs='?', type=int, | 
					
						
							|  |  |  |             const=15, default=False, | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  |             help='decrease current directory weight') | 
					
						
							|  |  |  |     # parser.add_argument( | 
					
						
							|  |  |  |             # '-b', '--bash', action="store_true", default=False, | 
					
						
							|  |  |  |             # help='enclose directory quotes to prevent errors') | 
					
						
							|  |  |  |     # parser.add_argument( | 
					
						
							|  |  |  |             # '--complete', action="store_true", default=False, | 
					
						
							|  |  |  |             # help='used for tab completion') | 
					
						
							| 
									
										
										
										
											2013-02-25 05:49:45 +00:00
										 |  |  |     parser.add_argument( | 
					
						
							|  |  |  |             '--purge', action="store_true", default=False, | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  |             help='remove non-existent paths from database') | 
					
						
							| 
									
										
										
										
											2013-02-25 05:49:45 +00:00
										 |  |  |     parser.add_argument( | 
					
						
							|  |  |  |             '-s', '--stat', action="store_true", default=False, | 
					
						
							| 
									
										
										
										
											2012-05-06 23:41:00 +00:00
										 |  |  |             help='show database entries and their key weights') | 
					
						
							| 
									
										
										
										
											2013-02-25 05:49:45 +00:00
										 |  |  |     parser.add_argument( | 
					
						
							| 
									
										
										
										
											2013-05-14 22:34:19 +00:00
										 |  |  |             '-v', '--version', action="version", version="%(prog)s " + | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  |             VERSION, help='show version information') | 
					
						
							| 
									
										
										
										
											2013-05-14 22:34:19 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     args = parser.parse_args() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-15 00:03:08 +00:00
										 |  |  |     if args.add: | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  |         add_path(config, args.add) | 
					
						
							| 
									
										
										
										
											2013-12-17 18:03:57 +00:00
										 |  |  |         return 0 | 
					
						
							| 
									
										
										
										
											2013-05-14 22:34:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-15 00:03:08 +00:00
										 |  |  |     if args.increase: | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  |         try: | 
					
						
							|  |  |  |             print_entry(add_path(config, os.getcwdu(), args.increase)) | 
					
						
							| 
									
										
										
										
											2013-12-17 18:03:57 +00:00
										 |  |  |             return 0 | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  |         except OSError: | 
					
						
							|  |  |  |             print("Current directory no longer exists.", file=sys.stderr) | 
					
						
							| 
									
										
										
										
											2013-12-17 18:03:57 +00:00
										 |  |  |             return 1 | 
					
						
							| 
									
										
										
										
											2013-05-14 22:34:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-15 00:03:08 +00:00
										 |  |  |     if args.decrease: | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  |         try: | 
					
						
							|  |  |  |             print_entry(decrease_path(config, os.getcwdu(), args.decrease)) | 
					
						
							| 
									
										
										
										
											2013-12-17 18:03:57 +00:00
										 |  |  |             return 0 | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  |         except OSError: | 
					
						
							|  |  |  |             print("Current directory no longer exists.", file=sys.stderr) | 
					
						
							| 
									
										
										
										
											2013-12-17 18:03:57 +00:00
										 |  |  |             return 1 | 
					
						
							| 
									
										
										
										
											2013-05-14 22:34:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-15 00:03:08 +00:00
										 |  |  |     if args.purge: | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  |         print("Purged %d entries." % purge_missing_paths(config)) | 
					
						
							| 
									
										
										
										
											2013-12-17 18:03:57 +00:00
										 |  |  |         return 0 | 
					
						
							| 
									
										
										
										
											2013-05-14 22:34:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-15 00:03:08 +00:00
										 |  |  |     if args.stat: | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  |         print_stats(config) | 
					
						
							| 
									
										
										
										
											2013-12-17 18:03:57 +00:00
										 |  |  |         return 0 | 
					
						
							| 
									
										
										
										
											2013-05-14 22:34:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  |     print(encode_local(find_matches(config, args.directory))) | 
					
						
							| 
									
										
										
										
											2013-12-17 18:03:57 +00:00
										 |  |  |     return 0 | 
					
						
							| 
									
										
										
										
											2013-05-15 02:58:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  |     # if args.complete: | 
					
						
							|  |  |  |         # config['match_cnt'] = 9 | 
					
						
							|  |  |  |         # config['ignore_case'] = True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # config['args'] = args | 
					
						
							| 
									
										
										
										
											2013-05-14 22:34:19 +00:00
										 |  |  |     return config | 
					
						
							| 
									
										
										
										
											2012-05-06 23:41:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-07 01:09:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  | def add_path(config, path, increment=10): | 
					
						
							| 
									
										
										
										
											2013-12-17 15:52:41 +00:00
										 |  |  |     """ | 
					
						
							|  |  |  |     Add a new path or increment an existing one. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     os.path.realpath() is not used because users prefer to have short, symlinked | 
					
						
							|  |  |  |     paths with duplicate entries in the database than a single canonical path. | 
					
						
							|  |  |  |     """ | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  |     path = decode(path).rstrip(os.sep) | 
					
						
							|  |  |  |     if path == os.path.expanduser('~'): | 
					
						
							|  |  |  |         return path, 0 | 
					
						
							| 
									
										
										
										
											2012-05-07 01:09:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  |     data = load(config) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if path in data: | 
					
						
							|  |  |  |         data[path] = sqrt((data[path]**2) + (increment**2)) | 
					
						
							| 
									
										
										
										
											2010-07-21 14:44:43 +00:00
										 |  |  |     else: | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  |         data[path] = increment | 
					
						
							| 
									
										
										
										
											2010-07-21 14:44:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  |     save(config, data) | 
					
						
							|  |  |  |     return path, data[path] | 
					
						
							| 
									
										
										
										
											2012-05-07 00:34:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-07 14:14:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  | def decrease_path(config, path, increment=15): | 
					
						
							|  |  |  |     """Decrease weight of existing path.""" | 
					
						
							|  |  |  |     path = decode(path).rstrip(os.sep) | 
					
						
							|  |  |  |     data = load(config) | 
					
						
							| 
									
										
										
										
											2012-04-07 14:14:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  |     data[path] = max(0, data[path]-increment) | 
					
						
							| 
									
										
										
										
											2013-05-15 02:58:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  |     save(config, data) | 
					
						
							|  |  |  |     return path, data[path] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-17 18:04:11 +00:00
										 |  |  | def detect_smartcase(needles): | 
					
						
							|  |  |  |     """ | 
					
						
							|  |  |  |     If any needles contain an uppercase letter then use case sensitive | 
					
						
							|  |  |  |     searching. Otherwise use case insensitive searching. | 
					
						
							|  |  |  |     """ | 
					
						
							|  |  |  |     return not any(imap(has_uppercase, needles)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  | def find_matches(config, needles, count=1): | 
					
						
							|  |  |  |     """Return [count] paths matching needles.""" | 
					
						
							|  |  |  |     entriefy = lambda tup: Entry(*tup) | 
					
						
							| 
									
										
										
										
											2013-12-17 18:15:39 +00:00
										 |  |  |     not_cwd = lambda entry: entry.path != os.getcwdu() | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  |     data = sorted( | 
					
						
							| 
									
										
										
										
											2013-12-17 18:15:39 +00:00
										 |  |  |             ifilter(not_cwd, imap(entriefy, load(config).iteritems())), | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  |             key=attrgetter('weight'), | 
					
						
							|  |  |  |             reverse=True) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if not needles: | 
					
						
							|  |  |  |         return first(data).path | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     sanitize = lambda x: decode(x).rstrip(os.sep) | 
					
						
							| 
									
										
										
										
											2013-12-17 16:54:55 +00:00
										 |  |  |     needles = map(sanitize, needles) | 
					
						
							|  |  |  |     ignore_case = detect_smartcase(needles) | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-17 17:54:40 +00:00
										 |  |  |     exact_matches = match_consecutive(needles, data, ignore_case) | 
					
						
							| 
									
										
										
										
											2012-05-06 23:41:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-17 17:01:18 +00:00
										 |  |  |     exists = lambda entry: os.path.exists(entry.path) | 
					
						
							| 
									
										
										
										
											2013-12-17 17:04:44 +00:00
										 |  |  |     result = first(ifilter(exists, exact_matches)) | 
					
						
							| 
									
										
										
										
											2013-12-17 17:54:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # TODO(ting|2013-12-17): remove debug print | 
					
						
							|  |  |  |     print(result) | 
					
						
							|  |  |  |     sys.exit(0) | 
					
						
							| 
									
										
										
										
											2013-12-17 17:04:44 +00:00
										 |  |  |     return result.path if result else u'' | 
					
						
							| 
									
										
										
										
											2012-05-06 23:41:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-17 17:54:40 +00:00
										 |  |  | def match_consecutive(needles, haystack, ignore_case=False): | 
					
						
							|  |  |  |     """ | 
					
						
							|  |  |  |     Matches consecutive needles at the end of a path. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     For example: | 
					
						
							|  |  |  |         needles = ['foo', 'baz'] | 
					
						
							|  |  |  |         haystack = [ | 
					
						
							|  |  |  |             (path="/foo/bar/baz", 10), | 
					
						
							|  |  |  |             (path="/foo/baz/moo", 10), | 
					
						
							|  |  |  |             (path="/moo/foo/baz", 10), | 
					
						
							|  |  |  |             (path="/foo/baz", 10)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         regex needle = re.compile(r''' | 
					
						
							|  |  |  |             foo     # needle #1 | 
					
						
							|  |  |  |             [^/]*   # all characters except os.sep zero or more times | 
					
						
							|  |  |  |             /       # os.sep | 
					
						
							|  |  |  |             [^/]*   # all characters except os.sep zero or more times | 
					
						
							|  |  |  |             baz     # needle #2 | 
					
						
							|  |  |  |             [^/]*   # all characters except os.sep zero or more times | 
					
						
							|  |  |  |             $       # end of string | 
					
						
							|  |  |  |             ''' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         result = [ | 
					
						
							|  |  |  |             (path="/moo/foo/baz", 10), | 
					
						
							|  |  |  |             (path="/foo/baz", 10)] | 
					
						
							|  |  |  |     """ | 
					
						
							|  |  |  |     regex_no_sep = '[^' + os.sep + ']*' | 
					
						
							|  |  |  |     regex_one_sep = regex_no_sep + os.sep + regex_no_sep | 
					
						
							|  |  |  |     regex_no_sep_end = regex_no_sep + '$' | 
					
						
							|  |  |  |     # can't use compiled regex because of flags | 
					
						
							|  |  |  |     needle = regex_one_sep.join(needles) + regex_no_sep_end | 
					
						
							|  |  |  |     regex_flags = re.IGNORECASE | re.UNICODE if ignore_case else re.UNICODE | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     found = lambda haystack: re.search( | 
					
						
							|  |  |  |             needle, | 
					
						
							|  |  |  |             haystack.path, | 
					
						
							|  |  |  |             flags=regex_flags) | 
					
						
							|  |  |  |     return ifilter(found, haystack) | 
					
						
							| 
									
										
										
										
											2013-12-17 16:54:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def match_regex(needles, haystack, ignore_case=False): | 
					
						
							| 
									
										
										
										
											2013-12-17 15:52:30 +00:00
										 |  |  |     """ | 
					
						
							|  |  |  |     Performs an exact match by combining all arguments into a single regex | 
					
						
							|  |  |  |     expression and finding matches. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     For example: | 
					
						
							|  |  |  |         needles = ['qui', 'fox'] | 
					
						
							|  |  |  |         regex needle = r'.*qui.*fox.*' | 
					
						
							|  |  |  |         haystack = [ | 
					
						
							|  |  |  |             (path="foobar", 10.0), | 
					
						
							|  |  |  |             (path="The quick brown fox jumped over the lazy dog", 12.3)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         result = [(path="The quick brown fox jumped over the lazy dog", 12.3)] | 
					
						
							|  |  |  |     """ | 
					
						
							|  |  |  |     regex_needle = '.*' + '.*'.join(needles) + '.*' | 
					
						
							| 
									
										
										
										
											2013-12-17 16:06:13 +00:00
										 |  |  |     regex_flags = re.IGNORECASE | re.UNICODE if ignore_case else re.UNICODE | 
					
						
							| 
									
										
										
										
											2013-12-17 16:54:55 +00:00
										 |  |  |     has_needle = lambda haystack: re.search(regex_needle, haystack.path, flags=regex_flags) | 
					
						
							|  |  |  |     return ifilter(has_needle, haystack) | 
					
						
							| 
									
										
										
										
											2013-12-17 02:28:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def purge_missing_paths(config): | 
					
						
							|  |  |  |     """Remove non-existent paths.""" | 
					
						
							|  |  |  |     exists = lambda x: os.path.exists(x[0]) | 
					
						
							|  |  |  |     old_data = load(config) | 
					
						
							|  |  |  |     new_data = dict(ifilter(exists, old_data.iteritems())) | 
					
						
							|  |  |  |     save(config, new_data) | 
					
						
							|  |  |  |     return len(old_data) - len(new_data) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def print_stats(config): | 
					
						
							|  |  |  |     data = load(config) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for path, weight in sorted(data.iteritems(), key=itemgetter(1)): | 
					
						
							|  |  |  |         print_entry(path, weight) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     print("________________________________________\n") | 
					
						
							|  |  |  |     print("%d:\t total weight" % sum(data.itervalues())) | 
					
						
							|  |  |  |     print("%d:\t number of entries" % len(data)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         print("%.2f:\t current directory weight" % data.get(os.getcwdu(), 0)) | 
					
						
							|  |  |  |     except OSError: | 
					
						
							|  |  |  |         pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     print("\ndata:\t %s" % config['data_path']) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def main(): | 
					
						
							| 
									
										
										
										
											2013-12-17 18:03:57 +00:00
										 |  |  |     return eval_arguments(parse_environment(set_defaults())) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-07 14:14:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-04 20:00:59 +00:00
										 |  |  | if __name__ == "__main__": | 
					
						
							| 
									
										
										
										
											2013-05-14 22:34:19 +00:00
										 |  |  |     sys.exit(main()) |