LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Software (https://www.linuxquestions.org/questions/linux-software-2/)
-   -   Program to recursively find images and rename to "cover.jpg" (https://www.linuxquestions.org/questions/linux-software-2/program-to-recursively-find-images-and-rename-to-cover-jpg-937348/)

strungoutfan78 03-30-2012 11:15 PM

Program to recursively find images and rename to "cover.jpg"
 
As the title suggests, I'm looking for a simple way to rename all the album art that has accumulated in my music folders over the years. I've used multiple music players in a never ending quest to find the perfect audio player, consequently ending up with a bazillion different jpg's and png's in my music sub-folders (due to stupid automatic cover downloading plugins) with ridiculously long names, such as:
Code:

Accept_-_Metal_Masters-front.jpg
rather than just "cover" or "folder".

What I want to do here is
  1. Search my music folder recursively and find all jpg's and png's
  2. either just completely remove them or change the name to "cover.jpg" or "cover.png" somehow

Ideally I envision a graphical interface that will find the files and display them to me, allowing me to then perform one of the actions I listed above. Does such a program exist? The closest thing that I've ever seen to this is a program written for Windows called Album Art Downloader. It is an awesome program and runs in wine, but sometimes gives me weird results. Is there a native Linux program similar? Many thanks.

**A caveat here is now I'm using xmms2 with xmms2tray, which uses dbus to display album art in the pop-ups. Every one of my albums has art, yet for some reason hardly any of it displays in the pop-up. Anyone know what the filename is that xmms2tray is looking for?

fukawi1 03-31-2012 03:24 AM

I have no idea about a GUI application. But from the command line it is quite easy, with "find".

Code:

# find . -name ".jpg" -exec mv {} cover.jpg \;
This would move them all to the . directory and rename them, you would need to specify the full path to the results directory, I'm not sure how to do this.

Alternatively you could replace "-exec mv {} cover.jpg \;" with -delete, to remove them completely.

strungoutfan78 04-01-2012 04:04 AM

That sounds like it will work. Do you know if I could use the rename command rather than delete? I'll probably just use delete and start from scratch as it will less painful, but for future reference?

catkin 04-01-2012 07:29 AM

Quote:

Originally Posted by fukawi1 (Post 4641236)
Code:

# find . -name ".jpg" -exec mv {} cover.jpg \;
This would move them all to the . directory and rename them ...

Beware! That would effectively delete them all except the last found because each successive mv would overwrite the previous ./cover.jpg

colucix 04-01-2012 07:43 AM

Quote:

Originally Posted by catkin (Post 4641928)
Beware! That would effectively delete them all except the last found because each successive mv would overwrite the previous ./cover.jpg

Good catch! Moving/deleting/renaming commands should be given carefully. Furthermore, the command above will not find anything but a hidden file named .jpg (it misses the wildcard). Try this instead:
Code:

find . -name '*.jpg' -execdir echo mv {} cover.jpg \;
Here the echo statement before mv just shows the commands to be executed, without actually execute them. In this way you can review the results and if all appears right, run again without echo. Notice the -execdir action addresses the problem raised by catkin: the command will be executed inside each directory where the JPG files are found! Hope this helps.

strungoutfan78 04-04-2012 10:35 AM

Thanks for the tip about -execdir and echo. I wasn't familiar with that. I've got so much multiple art though I think I'm just going to delete it and start fresh. What a pain. How would I use echo with delete?

TobiSGD 04-04-2012 10:47 AM

Quote:

Originally Posted by strungoutfan78 (Post 4644641)
How would I use echo with delete?

You wouldn't. You would have to use rm instead of the inbuilt -delete option. That would look like this:
Code:

find . -name '*.jpg' -exec echo rm '{}' \;
By the way, AFAIK the curly braces have to be escaped, therefore the single quotes around them.

catkin 04-04-2012 11:00 AM

Quote:

Originally Posted by TobiSGD (Post 4644647)
By the way, AFAIK the curly braces have to be escaped, therefore the single quotes around them.

It always used to be necessary but I routinely do not do so. IDK at what point it became unnecessary. From the GNU bash ref:
Code:

{}

              { list; }

    Placing a list of commands between curly braces causes the list to be executed in the current shell context. No subshell is created.

That does not define what happens when the list is empty.

Experimenting:
Code:

c@CW8:~$ echo {}
{}
c@CW8:~$ echo { echo foo > /dev/null }
[no output]

It would be nice to find a reference explaining that behaviour.

strungoutfan78 04-04-2012 11:07 PM

Quote:

Originally Posted by TobiSGD (Post 4644647)
You wouldn't. You would have to use rm instead of the inbuilt -delete option.

That's what I was wondering. Thanks for that.

matrix13 04-05-2012 09:03 AM

Also, use "-iname" instead of "-name" in you want to match case insensitively (*.jpg and *.JPG are different files in linux).

Use the following to find both *.jpg and *.png in one go.
Quote:

find . -iname '*.jpg" -o -iname '*.png' -exec echo rm '{}' \;
Hope this helps.

cascade9 04-05-2012 10:12 AM

I can understand wanting to remove 'excess' artwork......but why would you want them named 'folder.***' or 'cover.***'? Seems a bad idea to have 10s, 100s or 1000s or files with the same name, even if they are in different folders. I know some media players require 'cover.***' or 'folder.***' but that has always struck me as silly....and the media players I use with album art display dont have requirements like that.

I have no idea why xmms2tray wont display most of your album art. Try checking the art it will display, there are a few possibilities (like it gets the 1st pic file it finds, and tries to display it, but wont display images over 200x200, or wont display images that arent .jpeg, etc..). It might even be that it is only displaying artwork embedded into the tags....

strungoutfan78 04-05-2012 11:08 PM

Quote:

Originally Posted by matrix13 (Post 4645466)
Also, use "-iname" instead of "-name" in you want to match case insensitively (*.jpg and *.JPG are different files in linux).

Use the following to find both *.jpg and *.png in one go.

Hope this helps.

I will most likely do exactly that. Thanks for reminding me about -iname.

strungoutfan78 04-05-2012 11:18 PM

Quote:

Originally Posted by cascade9 (Post 4645525)
I have no idea why xmms2tray wont display most of your album art. Try checking the art it will display, there are a few possibilities (like it gets the 1st pic file it finds, and tries to display it, but wont display images over 200x200, or wont display images that arent .jpeg, etc..). It might even be that it is only displaying artwork embedded into the tags....

In all likelihood that's the real problem. I hardly have any art embedded in my ID3 tags, which probably correlates to the small percentage of songs which actually display art. The documentation on xmms2tray is slim to none. I emailed the developer to ask what type of file it is looking for but got absolutely no response. I guess I could browse the source code. Can't be too many lines of code. The only reason I would want to rename them all to "folder" or "cover" is simply to take a shot in the dark to see if it picks them up afterward. I guess I could use easytag to embed all the artwork, but 10,000+ songs is a lot when it won't allow me to do more than one song at a time. *sigh* :banghead:

Anyone know if exfalso do batch art embedding? (or any other program for that matter)

strungoutfan78 04-05-2012 11:35 PM

Well, I'm not too familiar with python, but i think I've found the relevant portion of code handling album art. Can anyone clarify what I'm looking at here? (HAVE_IMAGING is set to true as long as python imaging library is found, which it is in this case) Looks to me like it wants a 64x64 image and will resize to this if the original image is larger. This could be my problem because all my art is MINIMUM 500x500. Any thoughts?

Code:

def newsong(self,res):
        v = res.value()
       
        if isinstance(v, numbers.Integral):
            # this is the ID. I want the whole info.
            self.xmms.medialib_get_info(res.value(),self.newsong)
        else:
            if isinstance(v, basestring): # coverart
                info = self.curinfo
                coverimg = StringIO(v)
            elif v is None: # what?
                return
            else:
                info = v
                coverimg = None
                self.curinfo = info

            img = os.getcwd() + '/data/xmms2_64.png'
            if HAVE_IMAGING and 'picture_front' in info:
                if info['picture_front'] == self.lastimg[0]:
                    #same image, just use last.
                    img = self.lastimg[1]
                else:
                    if self.lastimg[1]:
                        #there is an old image to delete.
                        os.remove(self.lastimg[1])
                        self.lastimg = ('', '')
                    if coverimg:
                        orig_pic = Image.open(coverimg)
                        if orig_pic.size[1] <= 64:
                            sm_pic = orig_pic
                        else:
                            sm_pic = orig_pic.resize((64,64), Image.BICUBIC)
                        fname = '/tmp/xmms2tray_cover%08X.png' \
                                    % random.randint(0, 2**32-1)
                        sm_pic.save(fname)
                        self.lastimg = (info['picture_front'], fname)
                        img = fname
                    else:
                        self.xmms.bindata_retrieve(info['picture_front'],
                                                    self.newsong)
                        return


strungoutfan78 04-06-2012 12:17 AM

Well I did some more digging and found that it is only reading embedded art from the ID3 tags. That really blows. Guess I'll get started embedding one song at a time....:rolleyes:

strungoutfan78 04-06-2012 02:55 AM

OK so I was looking into how I could possibly do this through the command line when I stumbled across a little program called eyeD3. I can use it to embed album art from the command line fairly easy. All I have to do first is remove all but one image from each directory in my Music folder hierarchy. Then I'll use find in conjunction with rename (the Debian perl rename) to rename any remaining images to cover.jpg (simply to have one standard name to feed to eyeD3 later). My problem now is, I can't get the syntax right on the perl regular expressions to rename any file ending in ".jpg" to "cover.jpg". This is as close as I've come:
Code:

find ~/Music -type f -iname "*.jpg" -exec rename 's/*.jpg/cover.jpg/' \;
Now I know this is wrong because apparently "." is the perl wildcard representing any character. What would I replace "*.jpg" with in the rename arguments to catch any file ending in ".jpg"?

strungoutfan78 04-06-2012 03:35 AM

I'm over-complicating things here. I just really got stuck trying to figure out how to use this damn rename command.
Code:

find . -name '*.jpg' -execdir mv {} cover.jpg \;
Works just fine. I'll post my results regarding eyeD3 tomorrow. Need sleep. Thanks everyone for your assistance with this tonight.

David the H. 04-06-2012 01:34 PM

Quote:

Originally Posted by catkin (Post 4644661)
It always used to be necessary but I routinely do not do so. IDK at what point it became unnecessary. From the GNU bash ref:
Code:

{}

              { list; }

    Placing a list of commands between curly braces causes the list to be executed in the current shell context. No subshell is created.

That does not define what happens when the list is empty.

Experimenting:
Code:

c@CW8:~$ echo {}
{}
c@CW8:~$ echo { echo foo > /dev/null }
[no output]

It would be nice to find a reference explaining that behaviour.


I'm fairly sure that what happening is simply that the exact string {} has no special meaning to the shell. Since it doesn't correspond to any defined syntax, it gets passed on as a literal value to the command. It's similar in this way to what happens when you have a globbing pattern that doesn't match anything.

I would personally still go ahead and quote it anyway, if only to not have bash waste a cycle attempting to parse it for meaning first.

As for this:
Code:

echo { echo foo > /dev/null }
Since the first word in the line is a command name, all the rest of the "words" are treated as arguments to that command. The {list;} syntax doesn't apply in this situation (although it's certainly checked for correspondence to brace expansion syntax first, a-la my first point above).

So all the elements are read as individual literal strings, except for > /dev/null, which is a redirection. It doesn't particularly matter where on a line you put redirections, other than that they get associated with the correct command; they are always evaluated and set up first, and removed from the command list before the rest of the line is processed. That's why you're getting no output.

To demonstrate, take out the redirect, and you get this:
Code:

$ echo { echo foo }
{ echo foo }


strungoutfan78 04-06-2012 03:41 PM

David,

Thanks for that explanation. Makes sense.

---------- Post added 04-06-12 at 01:42 PM ----------

David,

Thanks for that explanation. Makes sense.

strungoutfan78 04-06-2012 03:43 PM

Wow quick reply is now giving me problems as well as not being able to edit previous posts. Anyone else experiencing issues with these forums? May just be my version of chromium.

catkin 04-06-2012 10:45 PM

Quote:

Originally Posted by David the H. (Post 4646628)
As for this:
Code:

echo { echo foo > /dev/null }
Since the first word in the line is a command name, all the rest of the "words" are treated as arguments to that command. The {list;} syntax doesn't apply in this situation (although it's certainly checked for correspondence to brace expansion syntax first, a-la my first point above).

Thanks David :)

That makes sense (what was I thinking of :redface:?!). Another demonstration:
Code:

c@CW8:~$ echo { echo foo > /dev/null; }
bash: syntax error near unexpected token `}'


David the H. 04-07-2012 05:58 AM

I've found that a large part of scripting comprehension depends on having a clear understanding of just how the shell parses the line, and in what order. Knowing what gets done before what helps immensely in figuring out situations like this.

Code:

$ echo { echo foo > /dev/null; }
bash: syntax error near unexpected token `}'

For anyone who can't figure this one out, the unquoted ";" is viewed as a command terminator, so it's really trying to run two commands in sequence, "echo +arguments" and "}" But of course the "}" keyword can't be used as a command name.

But check this out:

Code:

$ alias '}'='echo "Hi"'

$ echo { echo foo > /dev/null; }
Hi


strungoutfan78 04-07-2012 11:40 PM

Great example. :hattip:

cascade9 04-08-2012 02:53 AM

Quote:

Originally Posted by strungoutfan78 (Post 4646016)
Well I did some more digging and found that it is only reading embedded art from the ID3 tags. That really blows. Guess I'll get started embedding one song at a time....:rolleyes:

W.T.F. What sort of crazy did that?

"I know, I'll have the artwork displayed from the ID3 tags.....even though the FOSS codecs I should be supporting dont use ID3 tags normally, and can often have problems with ID3 tags when they are used, and who cares about the extra space being used from having artwork embedded into the tags".

Im a little disgusted by that. But then again, what should I expect from something with virtually no documentation?

Sorry about my little rant that doesnt really help your problem.

BTW, if you really like album art give deadbeef a try. You wont get album art in popups, well, AFAIK anyway, I never really tired to do that. It might not be a media player that suits someone who likes XMMS2 (or maybe that is just caused by my 'omg its bloody winamp' reaction from the appearance), but its worth a look.

It can be a little tricky to get the album art displayed, so if you do try deadbeef I can give you directions for how to display album art.

strungoutfan78 04-09-2012 03:18 AM

Quote:

Originally Posted by cascade9:4647535
It might not be a media player that suits someone who likes XMMS2 (or maybe that is just caused by my 'omg its bloody winamp' reaction from the appearance), but its worth a look.

I'm fairly certain you're confusing XMMS2 with the original XMMS. XMMS2 is simply a daemon that runs in the background. It has no default gui although many exist. It can be used as a streaming client as well.

cascade9 04-10-2012 06:01 AM

Yes, I was. My mistake, my bad. ;)

My own fault, I made that mistake when I was looking for media players that would do what I wanted (album art, and a non-standard playlist format).

strungoutfan78 04-10-2012 02:48 PM

Its all good. :cool: I like not having to interact with my audio player. Just set it and forget it. I do like having the little pop-ups with a small album art thumbnail though. 99% of the time I just shuffle my entire collection while working. Don't care much for library management or playlists. Pcnanfm works fine for library management. XMMS2 and openbox with custom keybinds works great for me. I just like it to be as unobtrusive as possible.

273 04-10-2012 03:14 PM

Easytag will allow you to tag more than one file at a time -- I found out after going through a couple of albums that you need to tick the box to the right of the album art image to do so. I don't recall exactly when in the process to do this but you ought to be able to work it out now you know the secret of the tick box.

strungoutfan78 04-10-2012 04:04 PM

Quote:

Originally Posted by 273:4649584
Easytag will allow you to tag more than one file at a time -- I found out after going through a couple of albums that you need to tick the box to the right of the album art image to do so. I don't recall exactly when in the process to do this but you ought to be able to work it out now you know the secret of the tick box.

I'll have to check that out. Thanks for the tip.

strungoutfan78 04-10-2012 11:18 PM

OMG I didn't even see that tiny little check box on the side of the album art. I'm completely familiar with using it on all the rest of the fields, just didn't even see it there. So this thread was all for naught. :redface: I think I'm still going to continue with eyeD3 though, as I just like learning new ways to do things. Thanks to everyone who chimed in on this thread. Honestly it went on quite a bit longer than I thought it would. Marking solved. :D

273 04-11-2012 03:43 AM

It's far from obvious so not surprised you missed it. Glad you've solved things anyhow.


All times are GMT -5. The time now is 10:50 PM.