Skip to content

Instantly share code, notes, and snippets.

@rcherny
Forked from omz/FileTransfer.py
Created November 21, 2016 02:10
Show Gist options
  • Select an option

  • Save rcherny/09d4aa1d38bc19a4b059fbf1c932afb9 to your computer and use it in GitHub Desktop.

Select an option

Save rcherny/09d4aa1d38bc19a4b059fbf1c932afb9 to your computer and use it in GitHub Desktop.

Revisions

  1. @omz omz revised this gist Apr 3, 2014. 1 changed file with 17 additions and 6 deletions.
    23 changes: 17 additions & 6 deletions FileTransfer.py
    Original file line number Diff line number Diff line change
    @@ -21,7 +21,7 @@
    from socket import gethostname
    import os
    from cStringIO import StringIO

    TEMPLATE = ('<!DOCTYPE html><html><head>' +
    '<link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.1.1/'+
    'css/bootstrap-combined.min.css" rel="stylesheet"></head><body>' +
    @@ -35,7 +35,7 @@
    '<button type="submit" class="btn btn-primary">Upload</button>' +
    '</div></form></p><hr/><h2>Download Files</h2>' +
    '{{FILES}}</div></body></html>')

    class TransferRequestHandler(BaseHTTPRequestHandler):
    def get_unused_filename(self, filename):
    if not os.path.exists(filename):
    @@ -51,7 +51,18 @@ def get_unused_filename(self, filename):
    def get_html_file_list(self):
    buffer = StringIO()
    buffer.write('<ul>')
    files = os.listdir('.')
    root_dir = os.path.expanduser('~/Documents')

    files = []
    for dn, dc, filenames in os.walk(root_dir):
    for fn in filenames:
    rel_dir = os.path.relpath(dn, root_dir)
    if rel_dir != '.':
    rel_file = os.path.join(rel_dir, fn)
    else:
    rel_file = fn
    files.append(rel_file)

    for filename in files:
    if os.path.splitext(filename)[1] == '.py':
    buffer.write('<li><a href="%s">%s</a></li>' % (filename, filename))
    @@ -89,7 +100,7 @@ def do_GET(self):
    self.send_header('Content-Type', 'text/html')
    self.end_headers()
    self.wfile.write(html)

    def do_POST(self):
    form = cgi.FieldStorage(fp=self.rfile, headers=self.headers,
    environ={'REQUEST_METHOD':'POST',
    @@ -118,7 +129,7 @@ def do_POST(self):
    '<div class="alert alert-success">%s</div>' % (message))
    html = html.replace('{{FILES}}', self.get_html_file_list())
    self.wfile.write(html)

    if __name__ == '__main__':
    console.clear()
    from BaseHTTPServer import HTTPServer
    @@ -129,4 +140,4 @@ def do_POST(self):
    print URL
    console.set_font()
    print 'Tap the stop button when you\'re done.'
    server.serve_forever()
    server.serve_forever()
  2. @omz omz created this gist Oct 2, 2012.
    132 changes: 132 additions & 0 deletions FileTransfer.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,132 @@
    # File Transfer for Pythonista
    # ============================
    # This script allows you to transfer Python files from
    # and to Pythonista via local Wifi.
    # It starts a basic HTTP server that you can access
    # as a web page from your browser.
    # When you upload a file that already exists, it is
    # renamed automatically.
    # From Pythonista's settings, you can add this script
    # to the actions menu of the editor for quick access.
    #
    # Get Pythonista for iOS here:
    # http://omz-software.com/pythonista

    from BaseHTTPServer import BaseHTTPRequestHandler
    import urlparse
    import urllib
    import cgi
    import editor
    import console
    from socket import gethostname
    import os
    from cStringIO import StringIO

    TEMPLATE = ('<!DOCTYPE html><html><head>' +
    '<link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.1.1/'+
    'css/bootstrap-combined.min.css" rel="stylesheet"></head><body>' +
    '<div class="navbar"><div class="navbar-inner">' +
    '<a class="brand" href="#">Pythonista File Transfer</a>' +
    '</div></div><div class="container">' +
    '<h2>Upload File</h2>{{ALERT}}'
    '<p><form action="/" method="POST" enctype="multipart/form-data">' +
    '<div class="form-actions">' +
    '<input type="file" name="file"></input><br/><br/>' +
    '<button type="submit" class="btn btn-primary">Upload</button>' +
    '</div></form></p><hr/><h2>Download Files</h2>' +
    '{{FILES}}</div></body></html>')

    class TransferRequestHandler(BaseHTTPRequestHandler):
    def get_unused_filename(self, filename):
    if not os.path.exists(filename):
    return filename
    basename, ext = os.path.splitext(filename)
    suffix_n = 1
    while True:
    alt_name = basename + '-' + str(suffix_n) + ext
    if not os.path.exists(alt_name):
    return alt_name
    suffix_n += 1

    def get_html_file_list(self):
    buffer = StringIO()
    buffer.write('<ul>')
    files = os.listdir('.')
    for filename in files:
    if os.path.splitext(filename)[1] == '.py':
    buffer.write('<li><a href="%s">%s</a></li>' % (filename, filename))
    buffer.write('</ul>')
    return buffer.getvalue()

    def do_GET(self):
    parsed_path = urlparse.urlparse(self.path)
    path = parsed_path.path
    if path == '/':
    html = TEMPLATE
    html = html.replace('{{ALERT}}', '')
    html = html.replace('{{FILES}}', self.get_html_file_list())
    self.send_response(200)
    self.send_header('Content-Type', 'text/html')
    self.end_headers()
    self.wfile.write(html)
    return
    file_path = urllib.unquote(path)[1:]
    if os.path.isfile(file_path):
    self.send_response(200)
    self.send_header('Content-Type', 'application/x-python')
    self.send_header('Content-Disposition',
    'attachment; filename=%s' % file_path)
    self.end_headers()
    with open(file_path, 'r') as f:
    data = f.read()
    self.wfile.write(data)
    else:
    html = TEMPLATE
    html = html.replace('{{ALERT}}',
    '<div class="alert alert-error">File not found</div>')
    html = html.replace('{{FILES}}', self.get_html_file_list())
    self.send_response(404)
    self.send_header('Content-Type', 'text/html')
    self.end_headers()
    self.wfile.write(html)

    def do_POST(self):
    form = cgi.FieldStorage(fp=self.rfile, headers=self.headers,
    environ={'REQUEST_METHOD':'POST',
    'CONTENT_TYPE':self.headers['Content-Type']})
    self.send_response(200)
    self.send_header('Content-Type', 'text/html')
    self.end_headers()
    field_item = form['file']
    uploaded_filename = None
    dest_filename = None
    file_data = field_item.file.read()
    file_len = len(file_data)
    uploaded_filename = field_item.filename
    dest_filename = self.get_unused_filename(uploaded_filename)
    with open(dest_filename, 'w') as f:
    f.write(file_data)
    editor.reload_files()
    del file_data
    html = TEMPLATE
    if uploaded_filename != dest_filename:
    message = '%s uploaded (renamed to %s).' % (uploaded_filename,
    dest_filename)
    else:
    message = '%s uploaded.' % (uploaded_filename)
    html = html.replace('{{ALERT}}',
    '<div class="alert alert-success">%s</div>' % (message))
    html = html.replace('{{FILES}}', self.get_html_file_list())
    self.wfile.write(html)

    if __name__ == '__main__':
    console.clear()
    from BaseHTTPServer import HTTPServer
    server = HTTPServer(('', 8080), TransferRequestHandler)
    URL = 'http://%s.local:8080' % gethostname()
    print 'Open this page in your browser:'
    console.set_font('Helvetica-Bold', 30)
    print URL
    console.set_font()
    print 'Tap the stop button when you\'re done.'
    server.serve_forever()