How to provide data for .po translation files? - django

After running django-admin.py makemessages -l de in Django to create the translation files, you could use a plain text editor or Poedit to fill them out.
Poedit has the advantage that it provides a specialized UI for entering this data. However I keep getting an error message when I switch between the words:
MyBookmarks/locale/de/LC_MESSAGES/django.po:7: header field
`Project-Id-Version' still has the initial default value
What is this? Has anyone with knowledge of internationalization in Django or general users of po / GNU gettext came across this error message?
Many Thanks,

I guess Django leave the header of the .po file customizable by the user, so is up to you to substitute "PACKAGE VERSION" with something more descriptive like "MY FABULOUS APP v.1.0".
To do that on any relevant file in a given path, you can use this command from the command line and in a *nix environment (or anywhere sed and find are available)
find <YOUR_PATH_HERE> -type f -name '*.po' -exec sed -e s'/PACKAGE VERSION/<YOUR_APP_NAME> <YOUR_APP_VERSION>/g' -i.bak {} \;
the command will replace the aforementioned text in every .po file and will save also an unmodified, backup file of each one.
So, in your case the command will be:
find MyBookmarks/ -type f -name '*.po' -exec sed -e s'/PACKAGE VERSION/MyBookmarks v.1.0/g' -i.bak {} \;
I routinely include this command in my fabfile and it solves the issue using POedit 1.5.x (but should work also on previous versions).
NOTE: You have to do that only once for every .po file. Next time you'll launch a ./manage.py makemessages Django will remember the setting.

Related

Using xargs, eval, and mv ensemble

I've been using the command line more frequently lately to increase my proficiency. I've created a .txt file containing URLs for libraries that I'd like to download. I batch-downloaded these files using
$ cat downloads.txt | xargs wget
When using the wget command I didn't specify a destination directory. I'd like to move each of the files that I've just downloaded into a directory called "vendor".
For the record, it has occurred to me that if I ran...
$ open .
...I could drag-and-drop these files into the desired directory. But in my opinion that would defeat the purpose of this exercise.
Now that I have the files in my cwd, I'd like to be able to target them and move them into the "vendor" directory.
As a side-question: Is there a useful way to print the most recently created files to STDOUT? Currently, I can grab the filenames from the URLs within downloads.txt pretty simply using the following pipeline and Perl script...
$ cat downloads.txt | perl -n -e 'if (/(?<=\/)([-.a-z]+)$/) { print $1 . "\n" }'
This will produce...
react.js
redux.js
react-dom.js
expect.js
...which is great as these are file that I intended on targeting. I'd like to transform each of these lines into a command within a pipeline that resembles this...
$ mv {./,./vendor/}<filename>
... where <filename> is "react.js" then "redux.js", and so forth.
I figure that I may be able to accomplish this using some combination of xargs, eval, and mv. This is where my bash skills drop-off.
Just to reiterate, I'm aware that the method in which I am approaching this problem is neither simple nor ideal. This is intentionally a convoluted exercise intended to stretch my bash knowledge.
Is there anyone who knows how I can use xargs, eval, and mv to accomplish this goal?
Thank you!
xargs -l -a downloads.txt basename | xargs -i mv {} ./vendor
How this works: The first instance of xargs reads the file names from downloads.txt and calls basename for each of these file names individually (alternatively, you could use basename -a). These basenames are then piped to another instance of xargs, which uses the arguments to call mv, replacing the string {} with the current argument.
mv $(basename -a $(<downloads.txt)) ./vendor
How this works: Since you want to move all the files into the same directory, you can use a single call to mv. The command substitution ("backticks") inserts the output of the command basename -a, which, in turn, reads its arguments from the file.

CHMOD 777 specific file extensions in Terminal

I am trying to CHMOD 777 all .doc files on my Mac. Is there is a way through Terminal that I could do this?
__
Thanks for the responses. I thought this was the way to change permissions on Word doc files. I have 2 users on Mac make that share a folder. But when one creates a doc file the other just has read permissions. I want both of them to have this, or everyone. It doesn'tmatter. I also want to go back and retroactively make all the past docs, some of which user A has read&write permissions, and some of which user B has read&write permissions for, read&writeable by both of them. Is there another way to do this? From what I can tell, this is a Mac permissions issue, nothing in Word. I thought CHMOD 777 in terminal was the way to do this.
Use find and xargs or the -exec option of find.
/home/erjablow> find . -name "*.doc" | xargs -n 3 chmod a+rwx
# Find the names of all "doc" files beneath the current directory.
# Gather them up 3 at a time, and execute
# chmod a+rwx file1 file2 file3
# on each set.
Now, find is a nasty utility, and hard to use. It can do ridiculous things, and one misspelling can ruin one's day.
Why do you want to make all doc files unprotected?
Don't.
If you really want to do this:
find / -x -name `*.doc` -type f -print0 | xargs -0 chmod 777
I have not tested this. I don't guarantee that the Mac versions of the find and xargs commands support all these options; I'm used to the GNU findutils versions that are common on Linux systems.
The find command starts at the root directory, limiting itself (-x) to the current filesystem, selects files whose names end in .doc, and prints them separated by null characters. The latter is necessary in case you have files or directories whose names contain spaces. The -x option is equivalent to the -xdev option in some other versions of find.
If you want to match files whose names in in .Doc, .DOC, etc., use -iname '*.doc' rather than -name '*.doc'.
The xargs command takes this null-delimited list of files and executes chmod 777 on each of them, breaking the list into chunks that won't overflow chmod's command line.
Let me emphasize again that:
I have not tested the above command. I don't currently have access to a MacOS system; I've just read the relevant man pages online. If you want to do a dry run, replace xargs by echo xargs; it will print the commands that it would execute (expect a lot of output with very long lines). Or replace xargs by xargs -n 1 echo to produce one line for each file.
Doing this in the first place is a bad idea. 777 gives read, write, and execute permission to every user on the system. .doc files are not executables; giving them execute permission makes no sense on a Unix-like system. 644 is likely to be a more sensible value (read/write for the owner, read-only for everyone else).
I agree with the previous response that find is nasty. And piping it to another utility can be tricky. If I had to do this, I'd specify the file type and use find's exec function instead of xargs.
find / -x -type f -iname *.doc \-exec chmod 777 {} \;
-x will search only the local Macintosh HD and exclude any mounted volumes
You may want to consider other criteria to refine the search, like a different starting point or excluding particular folders and/or file extensions
find / -x find / -not \( -path "*/some_sub-folder*" -or -path "*/some_other_sub-folder*" \) -type f \( -iname *.doc -or -iname *.docx \) \-exec chmod 777 {} \;
Or if you're set on using find|xargs, you should probably try -print instead of -print0 so that each file is returned as a separate line. That could fix it as well.
Either way, backup before doing this and test carefully. Good luck, HTH.

How to use shell magic to create a recursive etags using GNU etags?

The standard GNU etags does not support a recursive walk of directories as done by exuberant ctags -R. If I only have access to the GNU etags, how can I use bash shell magic to get etags to produce a TAGS table for all the C++ files *.cpp and *.h files in the current directory and all directories below the current one recursively to create a TAGS table in the current directory which has the proper path name for emacs to resolve the TAGS table entries.
The Emacs Wiki is often a good source for answers to common problems or best practices. For your specific problem there is a solution for both Windows and Unixen:
http://www.emacswiki.org/emacs/RecursiveTags#toc2
Basically you run a command to find all .cpp and all .h files (change file selectors if you use different file endings, such as e.g., .C) and pipe the result into etags. Since Windows does not seem to have xargs, you need a more recent version of etags that can read from stdin (note the dash at the end of the line which symbolizes stdin). Of course, if you use a recent version of etags, you can use the dash parameter instead of xargs there, too.
Windows:
cd c:\source-root
dir /b /s *.cpp *.h *.hpp | etags --your_options -
Unix:
cd /path/to/source-root
find . -name "*.cpp" -print -or -name "*.h" -print | xargs etags --append
This command creates etags file with default name "TAGS" for .c, .cpp, .Cpp, .hpp, .Hpp .h files recursively
find . -regex ".*\.[cChH]\(pp\)?" -print | etags -
Most of the answers posted here pipe the find output to xargs. This breaks if there are spaces in filenames inside the directory tree.
A more general solution that works if there are spaces in filenames (for .c and .h files) could be:
find . -name "*.[cChH]" -exec etags --append {} \;
Use find. man find if you need to.

Move all images in folder to subfolder, and update all references in text files to those images to their new location?

I have a folder which contains a ~50 text files (PHP) and hundreds of images. I would like to move all the images to a subfolder, and update the PHP files so any reference to those images point to the new subfolder.
I know I can move all the images quite easily (mv *.jpg /image, mv *.gif /image, etc...), but don't know how to go about updating all the text files - I assume a Regex has to be created to match all the images in a file, and then somehow the new directory has to be appended to the image file name? Is this best done with a shell script? Any help is appreciated (Server is Linux/CentOs5)
Thanks!
sed with the -i switch is probably what you're looking for. -i tells sed to edit the file in-place.
Something like this should work:
find /my/php/location -name '*.php' | xargs sed -ie 's,/old/location/,/new/location/,g'
You could do it like this:
#!/bin/sh
for f in *.jpg *.png *.gif; do
mv $f gfx/
for p in *.txt; do
sed -i bak s,`echo $f`,gfx/`echo $f`,g $p
done
done
It finds all jpg/png/gif files and moves them to the "gfx" subfolder, then for each txt file (or whatever kind of file you want it edited in) it uses "sed" in-place to alter the path.
Btw. it will create backup files of the edited files with the extra extension of "bak". This can be avoided by omitting the "bak" part in the script.
This will move all images to a subdir called 'images' and then change only links to image files by adding 'images/' just before the basename.
mkdir images
mv -f *.{jpg,gif,png,jpeg} images/
sed -i 's%[^/"'\'']\+\.\(gif\|jpg\|jpeg\|png\)%images/\0%g' *.php
If you have thousands of files, you may need to utilize find and xargs. So, a bit slower
find ./ -regex '.*\(gif\|jpg\|png\|jpeg\)' -exec mv {} /tmp \;
find ./ -name \*.php -print0 | \
xargs -0 sed -i 's%[^/"'\'']\+\.\(gif\|jpg\|jpeg\|png\)%images/\0%g' *.php
Caution, it will also change the path to images with remote urls. Also, make sure you have a full backup of your directory, php syntax and variable names might cause problems.

How to translate a Django application using Poedit?

I run django-admin makemessages -l ro -e html,txt,rml in the application's directory (above the locale directory) to generate the PO files. When I open a PO file with Poedit, e.g. locale/ro/LC_MESSAGES/django.po, I can not see where the message is being referenced. The paths from the catalog look like this:
#: admin.py:12 admin.py:23
so Poedit tries to open locale/ro/LC_MESSAGES/admin.py which of course does not exist.
Update:
find -path '*/locale/ro/LC_MESSAGES/django.po' -exec sed --in-place -r '/^#: / s/([a-zA-Z_./]+):([0-9]+)/..\/..\/..\/\1:\2/g' {} \+
fixes the paths, but I would still like to see this problem solved at its core.
I've also reported this on Django's bug tracker.
See the poedit-users mailing list thread (yes, that was the best place to ask).
Update: ​Poedit handles this case correctly since version 1.5.6.