Forum: Ruby Ruby script to rebuild a directory structure

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
A21ac5660dd979ab72baddba8ca3ae97?d=identicon&s=25 Emmek on Rails (emmek)
on 2009-04-01 23:48
I have the following problem to solve.

I have some logo images in the following directory structure:

/users/a/adam/logos/jdkajsdns.jpg
/users/a/alan/logos/skdjaksxa.jpg
(...)
/users/b/bob(...)
(...)
etc.
(there are also other directories and files in the structure and some
directories are empty; but I'd like to extract just the "branch" with
logo pictures)

Names of directories like "adam", "alan" are users logins in the
database. I need to transform that structure into something like this:

/logos/756/jdkajsdns.jpg
/logos/815/skdjaksxa.jpg
etc.

where 756 is the id of the user 'adam' and the 815 is the id of the user
'alan', etc.

So:
1) It could be possible to bind logins and ids by generating a text file
with pairs of these values from db and to write a script that transforms
the structure using such file. How should the proper ruby script look
like?
2) Is it possible to use script/console in Rails and solve the problem
just inside it?
B57c5af36f5c1f33243dd8b2dd9043b1?d=identicon&s=25 F. Senault (Guest)
on 2009-04-02 00:27
(Received via mailing list)
Le Wed, 1 Apr 2009 16:48:24 -0500, Emmek On rails a écrit :

> Names of directories like "adam", "alan" are users logins in the
> database. I need to transform that structure into something like this:
>
> /logos/756/jdkajsdns.jpg
> /logos/815/skdjaksxa.jpg
> etc.
/.../
> 2) Is it possible to use script/console in Rails and solve the problem
> just inside it?

Yeps.  Something like (completely untested) :

require "fileutils"
include FileUtils

Users.find(:all).each do |u|
  mkdir "/logos/#{u.id}"
  cp_r "/users/#{u.login[0..0]}/#{u.login}/logos/.", "/logos/#{u.id}"
end

You'll find what you're looking for in the FileUtils module :

http://www.ruby-doc.org/stdlib/libdoc/fileutils/rd...

Fred
A21ac5660dd979ab72baddba8ca3ae97?d=identicon&s=25 Emmek on Rails (emmek)
on 2009-04-02 13:21
> Users.find(:all).each do |u|
>   mkdir "/logos/#{u.id}"
>   cp_r "/users/#{u.login[0..0]}/#{u.login}/logos/.", "/logos/#{u.id}"
> end

Thanx for reply. It almost works but... what if a particular user does
not have logo image or even he doesn't have path like above? I supposed
there should be Dir.glob with "empty?" used somewhere in the code.

I wrote something like this:

require "fileutils"
include FileUtils

User.find(:all,:limit=>'20').each do |u|
  mkdir "public/uploaded/logos/#{u.id}"
  cp_r "public/uploaded/users/#{u.login[0..0]}/#{u.login}/logo/.",
"public/uploaded/logos/#{u.id}" unless
Dir.glob("public/uploaded/users/#{u.login[0..0]}/#{u.login}/logo").empty?
end

Ugly but it seems to be working.

I have another question: how to force this script to copy only jpg, png
and gif files from the "logo" directory? (there are also some mouldy php
files I don't need ANYMORE)
B57c5af36f5c1f33243dd8b2dd9043b1?d=identicon&s=25 F. Senault (Guest)
on 2009-04-02 18:56
(Received via mailing list)
Le Thu, 2 Apr 2009 06:20:56 -0500, Emmek On rails a écrit :

> I have another question: how to force this script to copy only jpg, png
> and gif files from the "logo" directory? (there are also some mouldy php
> files I don't need ANYMORE)

Even easier : iterate over Dir.glob("path/to/orig/**/*.{jpg,png,gif}").
(Add the File::FNM_CASEFOLD flag as a parameter if you have mixed case.)

Fred
A21ac5660dd979ab72baddba8ca3ae97?d=identicon&s=25 Emmek on Rails (emmek)
on 2009-04-02 20:22
F. Senault wrote:
>
> Even easier : iterate over Dir.glob("path/to/orig/**/*.{jpg,png,gif}").
> (Add the File::FNM_CASEFOLD flag as a parameter if you have mixed case.)
>
> Fred

Sorry, what do You exactly mean? I want to copy just images from
original location. I'm trying to do something with

cp_r "public/uploaded/users/#{u.login[0..0]}/#{u.login}/logo/."

but I don't know what to put at the end of this path to copy just jpgs,
gifs and pngs.
B57c5af36f5c1f33243dd8b2dd9043b1?d=identicon&s=25 F. Senault (Guest)
on 2009-04-02 21:30
(Received via mailing list)
Le Thu, 2 Apr 2009 13:22:01 -0500, Emmek on Rails a écrit :

> Sorry, what do You exactly mean? I want to copy just images from
> original location. I'm trying to do something with
>
> cp_r "public/uploaded/users/#{u.login[0..0]}/#{u.login}/logo/."
>
> but I don't know what to put at the end of this path to copy just jpgs,
> gifs and pngs.

It won't work that way ; cp_r copies the whole directories.  You need to
use Dir.glob or Find.find to select the files and then copy them one by
one.

Again, pretty much untested :

  Dir.chdir("/public/uploaded/users/#{u.login[0..0]}/#{u.login}/logo")
do
    Dir.glob("**/*.{jpg,png,gif}").each do |f|
      f2 = "/public/uploaded/logos/#{u.id}/#{f}"
      mkdir_p File.dirname(f2)
      cp_r f, f2
    end
  end

(You'll need at least to specify absolute paths if public isn't in the
root.)

Fred
This topic is locked and can not be replied to.