Question

Learning and understanding Python better I want to write a script based on youtube-dl that downloads a playlist and moves all those flv videos in a specific directory.

This is my code so far:

import shutil
import os
import sys
import subprocess
# Settings
root_folder = 'C:/Users/Robert/Videos/YouTube/Playlists/$s'

def download():
    files = open('Playlists.txt').readlines()

    for playlist in files:
        p = playlist.split(';')

    # Create the directory for the playlist if it does not exist yet
    if not os.path.exists (root_folder % p[0]):
        os.makedirs(root_folder % p[0])

    # Download every single video from the given playlist
    download_videos = subprocess.Popen([sys.executable, 'youtube-dl.py', ['-cit'], [p[1]]])        
    download_videos.wait()

    # Move the video into the playlist folder once it is downloaded
    shutil.move('*.flv', root_folder % p[0])


download()

The structure of my Playlists.txt looks as follows:

Playlist name with spaces;http://www.youtube.com/playlist?list=PLBECF255AE8287C0F&feature=view_all

I run into two problems. First of all the string formatting does not work.

I get the error:

Playlist name with spaces
Traceback (most recent call last):
  File ".\downloader.py", line 27, in <module>
    download()
  File ".\downloader.py", line 16, in download
    if not os.path.exists (root_folder % p[0]):
TypeError: not all arguments converted during string formatting

Can anybody explain me the reason? When I print p[0] everything looks fine.

Second, I do not have any clue how to set the correct shutil.move command to only move the flv video that was just downloaded. How can I filter that?

Thank you!

Was it helpful?

Solution

Disclaimer: I'm not on windows

The main point is that you should use os.path.join() for joining paths.

But there seems to be a couple of problems with this string:

root_folder = 'C:/Users/Robert/Videos/YouTube/Playlists/$s'

I think that:

  • you need to use double escaped backslahses.
  • You meant %s instead of $s.
  • There's no need anyway for %s, os.path.join() is the cross platform way for joining paths.
  • [optional] imho backsleshes are more readable.

So I'd say that you need to change that line to:

root_folder = 'C:/Users/Robert/Videos/YouTube/Playlists'

or

root_folder = 'C:\\Users\\Robert\\Videos\\YouTube\\Playlists'

or

root_folder = r'C:\Users\Robert\Videos\YouTube\Playlists'

And then do something like:

my_path = os.path.join(root_folder, p[0])
if not os.path.exists(my_path):
    # ...

Note: From the official os.path.join() doc:

Note that on Windows, since there is a current directory for each drive, os.path.join("c:", "foo") represents a path relative to the current directory on drive C: (c:foo), not c:\foo.

Judging by the useful Spencer Rathbun example, on windows you should get:

>>> os.path.join('C', 'users')
'C\\users'
>>> os.path.join('C:','users')
'C:users'

Which means that you must use either one of the following:

>>> os.path.join('C:/', 'users')
'C:\\users'
>>> os.path.join(r'C:\', 'users')
'C:\\users'

OTHER TIPS

$ sign is not a valid character for string formatting, use % instead:

root_folder = 'C:/Users/Robert/Videos/YouTube/Playlists/$s'
print root_folder % 'testfolder'

Gives me: 'TypeError: not all arguments converted during string formatting'

root_folder = 'C:/Users/Robert/Videos/YouTube/Playlists/%s'
print root_folder % 'testfolder'

Gives me: 'C:/Users/Robert/Videos/YouTube/Playlists/testfolder'

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top