<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -4,7 +4,7 @@ import sys
 from datetime import datetime, timedelta
 from optparse import make_option
 
-from django.core.management.base import NoArgsCommand
+from django.core.management.base import BaseCommand
 from django.conf import settings
 
 import S3
@@ -20,8 +20,8 @@ def _compress_string(s):
     zfile.close()
     return zbuf.getvalue()
 
-class Command(NoArgsCommand):
-    option_list = NoArgsCommand.option_list + (
+class Command(BaseCommand):
+    option_list = BaseCommand.option_list + (
         make_option('--verbose', action='store_true', dest='verbose',
             help = 'Verbose mode for you control freaks'),
         make_option('--no-gzip', action='store_true', dest='no_gzip',
@@ -32,17 +32,24 @@ class Command(NoArgsCommand):
     help = &quot;&quot;&quot;Upload static media files to a S3 bucket.
     
     Usage:
-        $cd static_media
-        $find * | grep -v &quot;.svn&quot; | .././manage.py upload_to_s3
+        There are 2 different ways to use this command.
     
-    Each line written to the STDIN must be a /path/to/file to be uploaded to a S3 bucket.
+        1) Each line written to the STDIN must be a /path/to/file to be uploaded to a S3 bucket.
+            $cd static_media
+            $find * | grep -v &quot;.svn&quot; | .././manage.py upload_to_s3
+            
+        2) Alternatively supply the /path/to/src_file &amp; /path/to/dest_file (S3 path)
+            $./manage.py upload_to_s3 --verbose static_media/css/widget_iphone.css css/widget_iphone.css
     &quot;&quot;&quot;
-    def handle_noargs(self, **options):
+    args = &quot;[SRC DEST]&quot;
+    
+    def _log(self, msg, error=False):
+        if self._verbose or error:
+            print msg
+    
+    def handle(self, *args, **options):
         # handle command-line options
-        verbose = options.get('verbose', False)
-        def log(msg, error=False):
-            if verbose or error:
-                print msg
+        self._verbose = options.get('verbose', False)
         
         no_gzip = options.get('no_gzip', False)
         no_expires = options.get('no_expires', False)
@@ -50,7 +57,7 @@ class Command(NoArgsCommand):
         if not ( hasattr(settings, &quot;AWS_ACCESS_KEY_ID&quot;) and 
                     hasattr(settings, &quot;AWS_SECRET_ACCESS_KEY&quot;) and
                     hasattr(settings, &quot;BUCKET_NAME&quot;) ):
-            log(
+            self._log(
                 &quot;Error: You need to add AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY &amp; BUCKET_NAME to your SETTINGS file\n&quot;,
                 error=True
             )
@@ -61,14 +68,12 @@ class Command(NoArgsCommand):
             BUCKET_NAME = settings.BUCKET_NAME
 
             conn = S3.AWSAuthConnection(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
-            for line in sys.stdin:
-                filename = os.path.normpath(line[:-1])
-                if filename == '.' or not os.path.isfile(filename):
-                    continue # Skip this, because it's not a file.
+            
+            def _upload(src, dest):
+                self._log(&quot;Uploading %s to s3:///%s/%s&quot; % (src, BUCKET_NAME, dest))
                 
-                log(&quot;Uploading %s&quot; % filename)
                 # guess content-type
-                content_type = mimetypes.guess_type(filename)[0]
+                content_type = mimetypes.guess_type(src)[0]
                 if not content_type:
                     content_type = 'text/plain'
                 upload_options = {
@@ -76,7 +81,7 @@ class Command(NoArgsCommand):
                     'Content-Type': content_type,
                 }
                 
-                filedata = open(filename, 'rb').read()
+                filedata = open(src, 'rb').read()
                 
                 # gzip compression
                 if not no_gzip:
@@ -89,7 +94,22 @@ class Command(NoArgsCommand):
                     expires = (datetime.now() + timedelta(days=FAR_FUTURE_EXPIRY)).strftime(HTTP_DATE)
                     upload_options['Expires'] = expires
                 
-                conn.put(
-                    BUCKET_NAME, filename, S3.S3Object(filedata),
-                    upload_options
-                )
+                resp = conn.put(
+                        BUCKET_NAME, dest, S3.S3Object(filedata),
+                        upload_options
+                    )
+                self._log(resp.message)
+
+            if len(args) == 0:
+                # no args supplied; let us look for input in STDIN
+                for line in sys.stdin:
+                    filename = os.path.normpath(line[:-1])
+                    if filename == '.' or not os.path.isfile(filename):
+                        continue # Skip this, because it's not a file.
+                    _upload(src=filename, dest=filename)
+            elif len(args) == 2:
+                # copy src file to dest
+                _upload(src=args[0], dest=args[1])
+            else:
+                self._log(&quot;ERROR - Takes in exactly 2 optional args. %d were supplied.&quot; % len(args), error=True)
+                sys.exit(1)</diff>
      <filename>management/commands/upload_to_s3.py</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>8873ff8fa9ea55e6c3c9c026543749a8f12f762e</id>
    </parent>
  </parents>
  <author>
    <name>Harish Mallipeddi</name>
    <email>harish.mallipeddi@gmail.com</email>
  </author>
  <url>http://github.com/mallipeddi/django-yslow/commit/7e435f00cebe4af47c99f3a564f2cd2eefd46fde</url>
  <id>7e435f00cebe4af47c99f3a564f2cd2eefd46fde</id>
  <committed-date>2008-05-28T21:09:24-07:00</committed-date>
  <authored-date>2008-05-28T21:09:24-07:00</authored-date>
  <message>Added support for uploading single file.</message>
  <tree>bda9900079a139883f06bdf0b2e745abe7fb02ba</tree>
  <committer>
    <name>Harish Mallipeddi</name>
    <email>harish.mallipeddi@gmail.com</email>
  </committer>
</commit>
