35
35
curses.KEY_DOWN: 'cursor_down',
36
36
curses.KEY_PPAGE: 'page_previous',
37
37
curses.KEY_BACKSPACE: 'page_previous',
38
0x02: 'page_previous', # Ctrl-B
38
0x02: 'page_previous', # Ctrl-B
39
39
curses.KEY_NPAGE: 'page_next',
40
40
ord(' '): 'page_next',
41
0x06: 'page_next', # Ctrl-F
41
0x06: 'page_next', # Ctrl-F
42
42
curses.KEY_HOME: 'home',
43
0x01: 'home', # Ctrl-A
43
0x01: 'home', # Ctrl-A
44
44
curses.KEY_END: 'end',
46
0x0C: 'cursor_center', # Ctrl-L
47
0x10: 'cursor_quarter_up', # Ctrl-P
48
0x231: 'cursor_quarter_up', # Ctrl-Cursor_up
49
0x0e: 'cursor_quarter_down', # Ctrl-N
50
0x208: 'cursor_quarter_down', # Ctrl-Cursor_down
47
52
# movement other pane
48
53
curses.KEY_SR: 'cursor_up_otherpane', # Shift-up
49
54
0x22f: 'cursor_up_otherpane', # Alt-up, kUP3
276
300
enter(othertab, allowexec=False)
277
301
return RET_HALF_UPDATE_OTHER
303
def cursor_quarter_up_otherpane(tab):
304
if app.prefs.options['manage_otherpane'] and \
305
tab.pane.mode in (PANE_MODE_LEFT, PANE_MODE_RIGHT):
306
delta = int(tab.pane.dims[0]/4)
307
othertab = app.noact_pane.act_tab
308
othertab.file_i -= delta
309
othertab.fix_limits()
310
return RET_HALF_UPDATE_OTHER
314
def cursor_quarter_down_otherpane(tab):
315
if app.prefs.options['manage_otherpane'] and \
316
tab.pane.mode in (PANE_MODE_LEFT, PANE_MODE_RIGHT):
317
delta = int(tab.pane.dims[0]/4)
318
othertab = app.noact_pane.act_tab
319
othertab.file_i += delta
320
othertab.fix_limits()
321
return RET_HALF_UPDATE_OTHER
281
326
def cursor_left(tab):
645
def __rename_backup_helper(tab):
647
fs = tab.selections[:]
649
filename = tab.get_file()
650
if filename == os.pardir:
656
fs = __rename_backup_helper(tab)
657
res = ProcessLoopRename('Rename files', files.do_rename, fs, tab.path).run()
662
def backup_file(tab):
663
fs = __rename_backup_helper(tab)
665
# pc is not used, just to check files have valid encoding
666
pc = files.PathContents(fs, tab.path)
668
messages.error('Backup files', 'Files with invalid encoding, convert first')
670
res = ProcessLoopBackup('Backup files', files.do_backup, fs, tab.path,
671
app.prefs.misc['backup_extension']).run()
599
676
def view_file(tab):
600
677
do_view_file(tab)
602
679
def edit_file(tab):
603
680
do_edit_file(tab)
682
def __copymove_helper(destdir, path, fs):
683
if destdir[0] != os.sep:
684
destdir = os.path.join(path, destdir)
685
dest_is_file = os.path.isfile(destdir)
686
dest_exists = os.path.exists(destdir)
687
# special case: no copy/move multiple files or dir over an existing file
688
if len(fs) > 1 and (dest_is_file or not dest_exists):
689
messages.error('Copying files \'%s\'' % destdir,
690
'Not a directory (20)')
691
return -1, None, None
693
if os.path.isdir(os.path.join(path, f)) and dest_is_file:
694
messages.error('Copying files \'%s\'' % destdir,
695
'Not a directory (20)')
696
return -1, None, None
697
# special case: copy/move a dir to same path with different name
700
if os.path.isdir(os.path.join(path, f)) and not dest_exists:
703
# special case: no copy/move to "<path>/non-existing-dir/not-existing-name"
704
# but permit copy/move to "<path>/not-existing-name"
705
dir_destdir = os.path.dirname(destdir)
706
# not (a and b) = not a or not b
707
# if os.path.dirname(destdir) != path and \
708
# not (os.path.isdir(os.path.dirname(destdir)) and not dest_exists):
709
if dir_destdir != path and (not os.path.isdir(dir_destdir) or dest_exists):
711
src = os.path.join(path, f)
712
dest = os.path.join(destdir, f)
713
if not os.path.exists(dest) and not dest_exists:
714
messages.error(dest, destdir)
715
messages.error('Copying files \'%s\'' % destdir,
716
'No such file or directory (2)')
717
return -1, None, None
718
return 0, destdir, rename_dir
606
721
destdir = app.noact_pane.act_tab.path + os.sep
607
722
if tab.selections:
616
731
destdir = doEntry(tab.path, 'Copy', buf, destdir)
618
res = ProcessCopyMoveLoop('Copying files', files.copy,
619
fs, tab.path, destdir).run()
733
st, destdir, rename_dir = __copymove_helper(destdir, tab.path, fs)
737
pc = files.PathContents(fs, tab.path)
740
messages.error('Copy files', 'Files with invalid encoding, convert first')
742
res = ProcessLoopCopy('Copy files', files.do_copy, pc,
743
destdir, rename_dir).run()
620
744
tab.selections = []
624
748
destdir = app.noact_pane.act_tab.path + os.sep
625
749
if tab.selections:
634
758
destdir = doEntry(tab.path, 'Move', buf, destdir)
636
res = ProcessCopyMoveLoop('Moving files', files.move,
637
fs, tab.path, destdir).run()
760
st, destdir, rename_dir = __copymove_helper(destdir, tab.path, fs)
764
pc = files.PathContents(fs, tab.path)
767
messages.error('Move files', 'Files with invalid encoding, convert first')
769
res = ProcessLoopCopy('Move files', files.do_copy, pc,
770
destdir, rename_dir).run()
771
if res != -1: # stopped by user
772
if isinstance(res, list): # don't delete files when not overwritten
774
tmp_delete_all = app.prefs.confirmations['delete']
775
app.prefs.confirmations['delete'] = 0
776
res = ProcessLoopDelete('Move files', files.do_delete, pc).run()
777
app.prefs.confirmations['delete'] = tmp_delete_all
638
778
tab.selections = []
643
fs = tab.selections[:]
645
filename = tab.get_file()
646
if filename == os.pardir:
649
res = ProcessRenameLoop('Renaming files', files.move, fs, tab.path).run()
654
781
def make_dir(tab):
655
782
newdir = doEntry(tab.path, 'Make directory', 'Type directory name')
699
831
menu = [ '@ Do something on file(s)',
701
833
'p Change file permissions, owner, group',
702
835
'g Gzip/gunzip file(s)',
703
836
'b Bzip2/bunzip2 file(s)',
704
'x Uncompress .tar.gz, .tar.bz2, .zip, .rar, .7z',
838
'x Uncompress .tar.gz, .tar.bz2, .tar.xz, .zip, .rar, .7z',
705
839
'u Uncompress .tar.gz, etc in other panel',
706
840
'c Compress directory to .tar.gz',
707
841
'd Compress directory to .tar.bz2',
842
'e Compress directory to .tar.xz',
708
843
'z Compress directory to .zip',
709
844
'r Compress directory to .rar',
710
845
'7 Compress directory to .7z' ]
908
1049
def do_execute_file(tab):
909
1050
filename = tab.get_file()
910
1051
parms = doEntry(tab.path, 'Execute file', 'Enter arguments')
913
1054
elif parms == '':
914
1055
cmd = get_escaped_filename(filename)
916
cmd = '%s \"%s\"' % (get_escaped_filename(filename), parms)
1057
cmd = '%s %s' % (get_escaped_filename(filename), parms)
918
st, msg = ProcessFunc('Executing file', filename,
919
run_shell, cmd, tab.path, True).run()
1059
st, msg = ProcessFunc('Executing file', encode(filename),
1060
run_shell, cmd, encode(tab.path), True).run()
921
1062
messages.error('Executing file', msg)
922
if st != -100 and msg != None:
1063
if st != -100 and msg is not None:
923
1064
if app.prefs.options['show_output_after_exec']:
924
1065
curses.curs_set(0)
925
1066
if messages.confirm('Executing file', 'Show output'):
926
1067
lst = [(l, 2) for l in msg.split('\n')]
927
pyview.InternalView('Output of "%s"' % cmd,
928
lst, center = 0).run()
1068
pyview.InternalView('Output of "%s"' % encode(cmd),
1069
lst, center=0).run()
929
1070
curses.curs_set(0)
963
1104
buf.append(('%s v%s executed by %s' % (LFM_NAME, VERSION, username), 5))
964
1105
buf.append(('<%s@%s> on a %s %s [%s]' % (user, host, so, ver, arch), 5))
965
1106
buf.append(('', 2))
966
cmd = get_escaped_command('file', fullfilename)
967
fileinfo = os.popen(cmd).read().split(':')[1].strip()
968
buf.append(('%s: %s (%s)' % (files.FILETYPES[file_data[0]][1], file,
1107
cmd = get_escaped_command('file -b', fullfilename)
1108
fileinfo = get_shell_output2(cmd)
1109
if fileinfo is None:
1110
fileinfo = 'no type information'
1111
buf.append(('%s: %s (%s)' % (files.FILETYPES[fd[0]][1], encode(file),
973
1116
path = vfs.join(tab) + ' [%s]' % tab.base
974
buf.append(('Path: %s' % path[-(curses.COLS-8):], 6))
975
buf.append(('Size: %s bytes' % file_data[files.FT_SIZE], 6))
1117
buf.append(('Path: %s' % encode(path[-(curses.COLS-8):]), 6))
1118
buf.append(('Size: %s bytes' % fd[files.FT_SIZE], 6))
976
1119
buf.append(('Mode: %s (%4.4o)' % \
977
(files.perms2str(file_data[files.FT_PERMS]),
978
file_data[files.FT_PERMS]), 6))
979
buf.append(('Links: %s' % file_data2[stat.ST_NLINK], 6))
1120
(files.perms2str(fd[files.FT_PERMS]),
1121
fd[files.FT_PERMS]), 6))
1122
buf.append(('Links: %s' % fde[0], 6))
980
1123
buf.append(('User ID: %s (%s) / Group ID: %s (%s)' % \
981
(file_data[files.FT_OWNER], file_data2[stat.ST_UID],
982
file_data[files.FT_GROUP], file_data2[stat.ST_GID]), 6))
983
buf.append(('Last access: %s' % ctime(file_data2[stat.ST_ATIME]), 6))
984
buf.append(('Last modification: %s' % ctime(file_data2[stat.ST_MTIME]), 6))
985
buf.append(('Last change: %s' % ctime(file_data2[stat.ST_CTIME]), 6))
1124
(fd[files.FT_OWNER], fde[1],
1125
fd[files.FT_GROUP], fde[2]), 6))
1126
buf.append(('Last access: %s' % ctime(fde[3]), 6))
1127
buf.append(('Last modification: %s' % ctime(fde[4]), 6))
1128
buf.append(('Last change: %s' % ctime(fde[5]), 6))
986
1129
buf.append(('Location: %d, %d / Inode: #%X (%Xh:%Xh)' % \
987
((file_data2[stat.ST_DEV] >> 8) & 0x00FF,
988
file_data2[stat.ST_DEV] & 0x00FF,
989
file_data2[stat.ST_INO], file_data2[stat.ST_DEV],
990
file_data2[stat.ST_INO]), 6))
991
fss = files.get_fs_info()
992
fs = ['/', '0', '0', '0', '0%', '/', 'unknown']
994
if fullfilename.find(e[5]) != -1 and (len(e[5]) > len(fs[5]) or e[5] == os.sep):
996
buf.append(('File system: %s on %s (%s) %d%% free' % \
997
(fs[0], fs[5], fs[6], 100 - int(fs[4][:-1])), 6))
998
pyview.InternalView('Information about \'%s\'' % file, buf).run()
1130
((fde[6] >> 8) & 0x00FF, fde[6] & 0x00FF,
1131
fde[7], fde[6], fde[7]), 6))
1132
mountpoint, device, fstype = files.get_mountpoint_for_file(fullfilename)
1133
buf.append(('File system: %s on %s (%s)' % \
1134
(device, mountpoint, fstype), 6))
1135
pyview.InternalView('Information about \'%s\'' % encode(file), buf).run()
1000
1137
if tab.selections:
1001
1138
for f in tab.selections:
1008
1145
# change permissions
1009
def __do_change_perms(filename, ret):
1010
ans = files.set_perms(filename, ret[0])
1012
messages.error('Chmod', '%s (%s)' % (ans, filename))
1013
ans = files.set_owner_group(filename, ret[1], ret[2])
1015
messages.error('Chown', '%s (%s)' % (ans, filename))
1146
def __do_change_perms(filename, perms, owner, group, recursive):
1148
ans = files.set_perms(filename, perms, recursive)
1150
messages.error('Chmod "%s"' % filename, '%s (%s)' % ans)
1151
ans = files.set_owner_group(filename, owner, group, recursive)
1153
messages.error('Chown "%s"' % filename, '%s (%s)' % ans)
1154
except UnicodeError:
1156
messages.error('Change permissions',
1157
'Files with invalid encoding, convert first')
1017
1160
def do_change_perms(tab):
1018
1161
if tab.selections:
1020
1163
for i, f in enumerate(tab.selections):
1021
1164
if not change_all:
1022
1165
ret = messages.ChangePerms(f, tab.files[f], i+1,
1040
1183
filename = os.path.join(tab.path, filename)
1041
__do_change_perms(filename, ret)
1184
__do_change_perms(filename, *ret[:-1])
1042
1185
app.regenerate()
1045
1188
# do show filesystems info
1046
1189
def do_show_fs_info():
1047
"""Show file systems info"""
1049
fs = files.get_fs_info()
1050
if type(fs) != type([]):
1051
messages.error('Show filesystems info', fs)
1191
fs = get_shell_output('df -h')
1192
except (IOError, os.error), (errno, strerror):
1193
messages.error('Show filesystems info', (strerror, errno))
1195
if fs is None or fs == '':
1196
messages.error('Show filesystems info', ('Can\'t run "df" command', 0))
1054
buf.append(('Filesystem FS type Total Mb Used Avail. Use% Mount point', 6))
1057
buf.append(('%-15s %-10s %7s %7s %7s %4s %s' % \
1058
(l[0], l[6], l[1], l[2], l[3], l[4], l[5]), 2))
1059
texts = [l[0] for l in buf]
1060
buf[1] = ('-' * len(max(texts)), 6)
1200
buf.append((fs[0].strip(), 6))
1201
buf.append(('-'*len(fs[0]), 6))
1203
buf.append((l.strip(), 2))
1061
1204
pyview.InternalView('Show filesystems info', buf).run()