Change default window sizes to accomodate courier font
[git-cola.git] / py / utils.py
blobae343659baf2b5f57f705ae627f20b70cffa6cf3
1 #!/usr/bin/env python
2 import os
3 import re
4 import time
5 import commands
6 from cStringIO import StringIO
8 KNOWN_FILE_TYPES = {
9 'ascii c': 'c.png',
10 'python': 'script.png',
11 'ruby': 'script.png',
12 'shell': 'script.png',
13 'perl': 'script.png',
14 'java': 'script.png',
15 'assembler': 'binary.png',
16 'binary': 'binary.png',
17 'byte': 'binary.png',
18 'image': 'image.png',
21 ICONSDIR = os.path.join (os.path.dirname (__file__), 'icons')
23 def ident_file_type (filename):
24 '''Returns an icon based on the contents of filename.'''
25 if os.path.exists (filename):
26 quoted_filename = shell_quote (filename)
27 fileinfo = commands.getoutput('file -b %s' % quoted_filename)
28 for filetype, iconname in KNOWN_FILE_TYPES.iteritems():
29 if filetype in fileinfo.lower():
30 return iconname
31 else:
32 return 'removed.png'
33 # Fallback for modified files of an unknown type
34 return 'generic.png'
36 def get_icon (filename):
37 '''Returns the full path to an icon file corresponding to
38 filename's contents.'''
39 icon_file = ident_file_type (filename)
40 return os.path.join (ICONSDIR, icon_file)
42 def get_staged_icon (filename):
43 '''Special-case method for staged items. These are only
44 ever 'staged' and 'removed' items in the staged list.'''
46 if os.path.exists (filename):
47 return os.path.join (ICONSDIR, 'staged.png')
48 else:
49 return os.path.join (ICONSDIR, 'removed.png')
51 def get_untracked_icon():
52 return os.path.join (ICONSDIR, 'untracked.png')
54 def get_directory_icon():
55 return os.path.join (ICONSDIR, 'dir.png')
57 def get_file_icon():
58 return os.path.join (ICONSDIR, 'generic.png')
60 def shell_quote (*inputs):
61 '''Quote strings so that they can be suitably martialled
62 off to the shell. This method supports POSIX sh syntax.
63 This is crucial to properly handle command line arguments
64 with spaces, quotes, double-quotes, etc.'''
66 regex = re.compile ('[^\w!%+,\-./:@^]')
67 quote_regex = re.compile ("((?:'\\''){2,})")
69 ret = []
70 for input in inputs:
71 if not input:
72 continue
74 if '\x00' in input:
75 raise AssertionError, ('No way to quote strings '
76 'containing null (\\000) bytes')
78 # = does need quoting else in command position it's a
79 # program-local environment setting
80 match = regex.search (input)
81 if match and '=' not in input:
82 # ' -> '\''
83 input = input.replace ("'", "'\\''")
85 # make multiple ' in a row look simpler
86 # '\'''\'''\'' -> '"'''"'
87 quote_match = quote_regex.match (input)
88 if quote_match:
89 quotes = match.group (1)
90 input.replace (quotes,
91 ("'" * (len(quotes)/4)) + "\"'")
93 input = "'%s'" % input
94 if input.startswith ("''"):
95 input = input[2:]
97 if input.endswith ("''"):
98 input = input[:-2]
99 ret.append (input)
100 return ' '.join (ret)
102 def get_tmp_filename():
103 # Allow TMPDIR/TMP with a fallback to /tmp
104 return '.ugit.%s.%s' % ( os.getpid(), time.time() )
106 HEADER_LENGTH = 80
107 def header (msg):
108 pad = HEADER_LENGTH - len (msg) - 4 # len (':+') + len ('+:')
109 extra = pad % 2
110 pad /= 2
111 return (':+'
112 + (' ' * pad)
113 + msg
114 + (' ' * (pad + extra))
115 + '+:'
116 + '\n')