Browse Source

Merge branch 'master' into remove-trailing-whitespace

Arnau Sanchez 6 years ago
parent
commit
0553e98cbf
6 changed files with 47 additions and 34 deletions
  1. 17 14
      README.md
  2. 0 12
      client_secrets.json
  3. 0 1
      setup.py
  4. 19 0
      youtube_upload/__main__.py
  5. 1 1
      youtube_upload/categories.py
  6. 10 6
      youtube_upload/main.py

+ 17 - 14
README.md

@@ -1,7 +1,7 @@
 Introduction
 ============
 
-_Youtube-upload_ is a command line Python script that uploads videos to Youtube (it should work on any platform -GNU/Linux, BSD, OS X, Windows, ...- that runs Python) using theYoutube [APIv3](https://developers.google.com/youtube/v3/).
+Command-line script to upload videos to Youtube using theYoutube [APIv3](https://developers.google.com/youtube/v3/). It should work on any platform (GNU/Linux, BSD, OS X, Windows, ...) that runs Python.
 
 Dependencies
 ============
@@ -12,7 +12,7 @@ Dependencies
 Check if your operating system provides those packages (check also those [deb/rpm/mac files](https://github.com/qiuwei/youtube-upload/releases)), otherwise install them with `pip`:
 
 ```
-$ sudo pip install --upgrade google-api-python-client progressbar2
+$ sudo pip install --upgrade google-api-python-client oauth2client progressbar2
 ```
 
 Install
@@ -25,19 +25,19 @@ $ cd youtube-upload-master
 $ sudo python setup.py install
 ```
 
-  * Or run directly from sources:
+Or run directly from sources:
 
 ```
 $ cd youtube-upload-master
 $ PYTHONPATH=. python bin/youtube-upload ...
 ```
 
-Authentication
-==============
+Setup
+=====
 
 You'll see that there is no email/password options. Instead, the Youtube API uses [OAuth 2.0](https://developers.google.com/accounts/docs/OAuth2) to authenticate the upload. The first time you try to upload a video, you will be asked to follow a URL in your browser to get an authentication token. If you have multiple channels for the logged in user, you will also be asked to pick which one you want to upload the videos to. You can use multiple credentials, just use the option ```--credentials-file```. Also, check the [token expiration](https://developers.google.com/youtube/v3/) policies.
 
-The package includes a default ```client_secrets.json``` file. If you plan to make a heavy use of the script, please [create and use your own OAuth 2.0 file](https://developers.google.com/youtube/registering_an_application), it's a free service. Steps:
+The package used to include a default ```client_secrets.json``` file. It does not work anymore, Google has revoked it. So you now must [create and use your own OAuth 2.0 file](https://developers.google.com/youtube/registering_an_application), it's a free service. Steps:
 
 * Go to the Google [console](https://console.developers.google.com/).
 * _Create project_.
@@ -46,12 +46,14 @@ The package includes a default ```client_secrets.json``` file. If you plan to ma
 * Side menu: _APIs & auth_ -> _Credentials_.
 * _Create a Client ID_: Add credentials -> OAuth 2.0 Client ID -> Other -> Name: youtube-upload -> Create -> OK
 * _Download JSON_: Under the section "OAuth 2.0 client IDs". Save the file to your local system. 
-* Use this JSON as your credentials file: ```--client-secrets=CLIENT_SECRETS```
+* Use this JSON as your credentials file: `--client-secrets=CLIENT_SECRETS` or copy it to `~/client_secrets.json`.
+
+*Note: ```client_secrets.json``` is a file you can download from the developer console, the credentials file is something auto generated after the first time the script is run and the google account sign in is followed, the file is stored at ```~/.youtube-upload-credentials.json```.*
 
 Examples
 ========
 
-* Upload a video:
+* Upload a video (a valid `~/.client_secrets.json` should exist, check the Setup section):
 
 ```
 $ youtube-upload --title="A.S. Mutter" anne_sophie_mutter.flv
@@ -62,16 +64,17 @@ pxzZ-fYjeYs
 
 ```
 $ youtube-upload \
-  --title="A.S. Mutter" 
+  --title="A.S. Mutter" " \
   --description="A.S. Mutter plays Beethoven" \
-  --category=Music \
+  --category="Music" \
   --tags="mutter, beethoven" \
   --recording-date="2011-03-10T15:32:17.0Z" \
   --default-language="en" \
   --default-audio-language="en" \
-  --client-secrets=my_client_secrets.json \
-  --credentials-file=my_credentials.json \
-  --playlist "My favorite music" \
+  --client-secrets="my_client_secrets.json" \
+  --credentials-file="my_credentials.json" \
+  --playlist="My favorite music" \
+  --embeddable=True|False \
   anne_sophie_mutter.flv
 tx2Zb-145Yz
 ```
@@ -121,7 +124,7 @@ Get available categories
 
 And see the JSON response below. Note that categories with the attribute `assignable` equal to `false` cannot be used.
 
-Using `shoogle`:
+Using [shoogle](https://github.com/tokland/shoogle):
 
 ```
 $ shoogle execute --client-secret-file client_secret.json \

+ 0 - 12
client_secrets.json

@@ -1,12 +0,0 @@
-{
-    "installed": {
-        "auth_uri": "https://accounts.google.com/o/oauth2/auth",
-        "client_secret": "8dRh9GAzr9Z4sTk_km9HrrcI",
-        "token_uri": "https://accounts.google.com/o/oauth2/token",
-        "client_email": "",
-        "redirect_uris": ["urn:ietf:wg:oauth:2.0:oob", "oob"],
-        "client_x509_cert_url": "",
-        "client_id": "911313852664-tir6o945mdn2bouorhpalkecrg23dng9.apps.googleusercontent.com",
-        "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs"
-    }
-}

+ 0 - 1
setup.py

@@ -10,7 +10,6 @@ setup_kwargs = {
     "author_email": "pyarnau@gmail.com",
     "url": "https://github.com/tokland/youtube-upload",
     "packages": ["youtube_upload/", "youtube_upload/auth"],
-    "data_files": [("share/youtube_upload", ['client_secrets.json'])],
     "scripts": ["bin/youtube-upload"],
     "license": "GNU Public License v3.0",
     "long_description": " ".join(__doc__.strip().splitlines()),

+ 19 - 0
youtube_upload/__main__.py

@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+from __future__ import unicode_literals
+
+# Execute with
+# $ python youtube_upload/__main__.py (2.6+)
+# $ python -m youtube_upload          (2.7+)
+
+import sys
+
+if __package__ is None and not hasattr(sys, 'frozen'):
+    # direct call of __main__.py
+    import os.path
+    path = os.path.realpath(os.path.abspath(__file__))
+    sys.path.insert(0, os.path.dirname(os.path.dirname(path)))
+
+import youtube_upload.main
+
+if __name__ == '__main__':
+    youtube_upload.main.main(sys.argv[1:])

+ 1 - 1
youtube_upload/categories.py

@@ -19,7 +19,7 @@ IDS = {
     "Gaming": 20,
     "Videoblogging": 21,
     "People & Blogs": 22,
-    "Comedy": 34,
+    "Comedy": 23,
     "Entertainment": 24,
     "News & Politics": 25,
     "Howto & Style": 26,

+ 10 - 6
youtube_upload/main.py

@@ -20,6 +20,7 @@ import sys
 import optparse
 import collections
 import webbrowser
+from io import open
 
 import googleapiclient.errors
 import oauth2client
@@ -123,8 +124,10 @@ def upload_youtube_video(youtube, options, video_path, total_videos, index):
 
         },
         "status": {
+            "embeddable": options.embeddable,
             "privacyStatus": ("private" if options.publish_at else options.privacy),
             "publishAt": options.publish_at,
+            "license": options.license,
 
         },
         "recordingDetails": {
@@ -145,12 +148,8 @@ def upload_youtube_video(youtube, options, video_path, total_videos, index):
 def get_youtube_handler(options):
     """Return the API Youtube object."""
     home = os.path.expanduser("~")
-    default_client_secrets = lib.get_first_existing_filename(
-        [sys.prefix, os.path.join(sys.prefix, "local")],
-        "share/youtube_upload/client_secrets.json")
     default_credentials = os.path.join(home, ".youtube-upload-credentials.json")
-    client_secrets = options.client_secrets or default_client_secrets or \
-        os.path.join(home, ".client_secrets.json")
+    client_secrets = options.client_secrets or os.path.join(home, ".client_secrets.json")
     credentials = options.credentials_file or default_credentials
     debug("Using client secrets: {0}".format(client_secrets))
     debug("Using credentials file: {0}".format(credentials))
@@ -212,6 +211,9 @@ def main(arguments):
         default="public", help='Privacy status (public | unlisted | private)')
     parser.add_option('', '--publish-at', dest='publish_at', metavar="datetime",
        default=None, help='Publish date (ISO 8601): YYYY-MM-DDThh:mm:ss.sZ')
+    parser.add_option('', '--license', dest='license', metavar="string",
+       choices=('youtube', 'creativeCommon'), default='youtube',
+       help='License for the video, either "youtube" (the default) or "creativeCommon"')
     parser.add_option('', '--location', dest='location', type="string",
         default=None, metavar="latitude=VAL,longitude=VAL[,altitude=VAL]",
         help='Video location"')
@@ -230,6 +232,8 @@ def main(arguments):
     parser.add_option('', '--title-template', dest='title_template',
         type="string", default="{title} [{n}/{total}]", metavar="string",
         help='Template for multiple videos (default: {title} [{n}/{total}])')
+    parser.add_option('', '--embeddable', dest='embeddable', default=True,
+        help='Video is embeddable')
 
     # Authentication
     parser.add_option('', '--client-secrets', dest='client_secrets',
@@ -255,7 +259,7 @@ def main(arguments):
         run_main(parser, options, args)
     except googleapiclient.errors.HttpError as error:
         response = bytes.decode(error.content, encoding=lib.get_encoding()).strip()
-        raise RequestError("Server response: {0}".format(response))
+        raise RequestError(u"Server response: {0}".format(response))
 
 def run():
     sys.exit(lib.catch_exceptions(EXIT_CODES, main, sys.argv[1:]))