summaryrefslogtreecommitdiff
path: root/ftp-list.py
diff options
context:
space:
mode:
authorPeter Wu <lekensteyn@gmail.com>2013-06-26 20:00:08 +0200
committerPeter Wu <lekensteyn@gmail.com>2013-06-26 20:00:08 +0200
commiteb5736156bdb736f8197d92fc83b799586ae492e (patch)
treefceeab2428b1935c520c2c92bb22f03126b836a3 /ftp-list.py
parent82c07bc02cafe9b8d6cb9fa2362b2ba6326d6a7b (diff)
downloadscripts-eb5736156bdb736f8197d92fc83b799586ae492e.tar.gz
ftp*.py: add FTP scripts
- ftp-get.py: sequentially download a list of files with one connection. - ftp-list.py: recursively show directory contents. - ftp.py: supports "MLSD" which is missing in inetutils.
Diffstat (limited to 'ftp-list.py')
-rwxr-xr-xftp-list.py100
1 files changed, 100 insertions, 0 deletions
diff --git a/ftp-list.py b/ftp-list.py
new file mode 100755
index 0000000..1b65832
--- /dev/null
+++ b/ftp-list.py
@@ -0,0 +1,100 @@
+#!/usr/bin/python
+# Recursively list FTP directory contents
+#
+# Copyright (C) 2013 Peter Wu <lekensteyn@gmail.com>
+
+# Prepend directory name to files and list files:
+# awk '/^Directory/{if($0 != "Directory /")dir=substr($0, index($0, "/"))}/^-/{n=index($0,$9);print substr($0,1, n - 1) dir "/" substr($0,n)}'
+
+import sys
+from ftplib import FTP
+import re
+
+user = "anonymous"
+passwd = "anon"
+host = None
+port = 21
+path = "/"
+
+patt_url = re.compile(r"""
+^
+(?:ftp://)?
+(?:
+ (?P<user>.+?)
+ (?:
+ :(?P<passwd>.+?)
+ )?
+ @
+)?
+(?P<host>[a-zA-Z0-9.-]+)
+(:(?P<port>\d+))?
+(?P<path>/.*)?
+$
+""", re.VERBOSE)
+
+if len(sys.argv) >= 2:
+ m = patt_url.match(sys.argv[1])
+ if m:
+ if m.group("user") is not None:
+ user = m.group("user")
+ if m.group("passwd") is not None:
+ passwd = m.group("passwd")
+ host = m.group("host")
+ if m.group("port") is not None:
+ port = int(m.group("port"))
+ if m.group("path") is not None:
+ path = m.group("path")
+
+if host is None:
+ print("Usage: python", sys.argv[0],
+ "[ftp://][user[:pass]@]ftp.example.com[:21][/path]",
+ file=sys.stderr)
+ sys.exit(1)
+
+# directories for which the contents needs to be retrieved
+dirs = []
+dirs.append(path)
+
+patt_list = re.compile(r"""
+^
+.[-rwxXst]{9}\ + # permissions
+\d+\ + # links count
+\S+\ + # owner
+\S+\ + # group
+\d+\ + # size
+\S{3}\ + # month
+\d{2}\ + # day
+(?:\d{4,}|\d{2}:\d{2}) # year or time
+\ (.+?) # name
+(?:\ ->\ (.+))? # symlink
+[\r\n]* # line contains
+$
+""", re.VERBOSE)
+
+def get_ls_processor(cwd):
+ def process_dir(line):
+ print(line)
+ if line[0] == 'd':
+ m = patt_list.match(line)
+ name = m.group(1)
+ if cwd == "/":
+ dir = "/" + name
+ else:
+ dir = cwd + "/" + name
+ print("Queuing", dir, file=sys.stderr)
+ dirs.append(dir)
+# elif line[0] == 'l':
+# m = patt_list.match(line)
+# print("Link", m.group(2))
+ return process_dir
+
+with FTP() as ftp:
+ ftp.connect(host, port)
+ ftp.login(user, passwd)
+ print(ftp.getwelcome(), file=sys.stderr)
+ while dirs:
+ dir = dirs.pop()
+ ftp.cwd(dir)
+ print("Directory", ftp.pwd())
+ ftp.retrlines('LIST', get_ls_processor(dir))
+ print("Queue size:", len(dirs), file=sys.stderr)