Reputation: 430
I have a script that loads songs and each song's data from a db (using peewee) and then downloads each song.
for music in musiclibrary.select().where(musiclibrary.downloaded == 0):
if not os.path.exists("mp3s/" + music.category + "/" + music.artist_name):
os.makedirs("mp3s/" + music.category + "/" + music.artist_name)
if not os.path.exists("mp3s/" + music.category + "/" + music.artist_name +
"/" + music.album_name):
os.makedirs("mp3s/" + music.category + "/" + music.artist_name +
"/" + music.album_name)
sub_dir = ("mp3s/" + music.category + "/" + music.artist_name +
"/" + music.album_name)
song = requests.get(music.song_mp3_url, timeout=(3,9))
if song.status_code == 200:
try:
with open(os.path.join(sub_dir, song_name), "wb") as f:
for chunk in song.iter_content(chunk_size=1024):
if chunk:
f.write(chunk)
except Exception as e:
print "exp is", e
return
I'm getting
exp is [Errno 2] No such file or directory: u'mp3s/letmiat/\u0627\u0644\u0633\u064a\u062f \u062d\u0633\u064a\u0646 \u0627\u0644\u0645\u0627\u0644\u0643\u064a/\u0644\u0637\u0645\u064a\u0627\u062a \u0645\u062a\u0641\u0631\u0642\u0629 \\\u06357\u0644\u0645\u0627\u0644\u0643\u064a/\u0644\u0637\u0645\u064a7\u0644\u0645\u0627\u0644\u0643\u064a/\u0644\u0637\u0645\u064a\u0627\u062a.mp3
This error occurs even though the directory already exists. The song name, album name, and artist name are mostly Arabic. I'm running this under Windows.
EDIT
I have a script (run.py) that calls this script (downloader.py) after some other script (written in scrapy) finnishes. run.py is in the project root folder, and downloader.py is one level under it. Just to be sure, I've put the mp3s folder in both places. Here is how it looks
-project
--run.py
--mp3s
---downloader.py
---mp3s
Upvotes: 0
Views: 1710
Reputation: 34270
If I split the name reported in the error on "/", I get 6 components instead of 5, and one of the components is actually 2 because it contains " \", i.e. a space followed by a backslash. That's two problems. Obviously the embedded backslash is a problem. Also, the first component in this pair ends in a space. Windows strips off this space character when os.makedirs
creates the directory. However, Windows does not strip off the trailing space from a non-final path component, such as when you try to create the mp3 file.
You need to ensure each path component is valid, i.e. that it contains no reserved characters -- i.e. ASCII control characters (ordinals 0-31), backslash, forward slash, pipe, colon, or the wildcard characters (question mark, asterisk, less than, greater than, and double quote); is not a DOS device name (CON, CONIN$, CONOUT$, PRN, AUX, NUL, COM[1-9], and LPT[1-9]); and doesn't end with a space or period (dot).
Upvotes: 1
Reputation: 1818
Verify that it is not a unicode issue by writting a test:
def test_ascii_writing():
with open('test.txt', "w") as f:
f.write('TESTING')
def test_unicode_writing():
with open(u'\u0627.txt', "w") as f:
f.write('TESTING')
test_ascii_writing()
test_unicode_writing()
If that test passes, I would guess the problem is you're assuming the category/artist/album folder chain already exists when it doesn't.
If you have a folder called mp3 and it is empty, and want to write the file for the song "Come Together" by The Beatles:
import os
os.mkdir('mp3/Rock')
os.mkdir('mp3/Rock/Beatles')
os.mkdir('mp3/Rock/Beatles/AbbeyRoad')
Before you can do:
with open('mp3/Rock/Beatles/AbbeyRoad', "wb") as f:
for chunk in song.iter_content(chunk_size=1024):
if chunk:
f.write(chunk)
Upvotes: 1