diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-07-19 02:26:00 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-07-19 02:31:58 +0300 |
commit | 8335e1d85fe5cc6a9fc0146a1edf5f94aacdae6b (patch) | |
tree | 2fedb59f1d083e4473bfcfa42954881fdd72cd51 | |
parent | ebf9c1844f18aa22d49504d4deab4da0dbac6fc7 (diff) | |
download | idest-8335e1d85fe5cc6a9fc0146a1edf5f94aacdae6b.tar.gz idest-8335e1d85fe5cc6a9fc0146a1edf5f94aacdae6b.tar.bz2 |
Update
-rw-r--r-- | doc/idest.texi | 256 | ||||
-rw-r--r-- | examples/Makefile.am | 5 | ||||
-rw-r--r-- | examples/dry-run.scm | 14 | ||||
-rw-r--r-- | examples/settitle.scm | 11 | ||||
-rw-r--r-- | src/cmdline.opt | 2 |
5 files changed, 230 insertions, 58 deletions
diff --git a/doc/idest.texi b/doc/idest.texi index f88b42a..bd6bad9 100644 --- a/doc/idest.texi +++ b/doc/idest.texi @@ -75,2 +75,3 @@ documents IdEst @value{VERSION}. * Modify:: Modifying Existing Tags +* Copy:: Copying Tags Between Files * Delete:: Deleting Tags and Frames @@ -192,3 +193,3 @@ which identifies a frame. There are frames that can appear only once in a tag, and there are -such that can appear multiple times. These latter have some +ones that can appear multiple times. These latter have some additional fields which serve to discern between them. In @@ -217,2 +218,3 @@ descriptor @samp{my-comment}, no matter what their language. +@anchor{list-frames} @xopindex{list-frames, introduced} @@ -235,2 +237,3 @@ short description of this frame purpose. +@anchor{filter--list-frames} @xopindex{filter, introduced} @@ -285,2 +288,3 @@ genre: Folk +@anchor{filter--query} @xopindex{filter, in query mode} @@ -319,3 +323,3 @@ Encoded by: lame To describe frames in a verbose manner, use the @option{--describe} -(@option{-D}) option'' +(@option{-D}) option: @@ -428,10 +432,10 @@ $ idest --set comment:eng:My_comment='Noise reduction on' track01.mp3 -If a comment with this content descriptor exists, its content will be -replaced with the new one. If not, a new comment frame will be -created. +In the example above, if a comment with this content descriptor +exists, its content will be replaced with the new one. If not, a new +comment frame will be created. -If comment is given without a particular content descriptor, all -existing comments will be removed and a new comment frame will be -added. Its content descriptor field will be empty and its -language field will be set to @samp{XXX}. +If a frame which can appear multiple times (such as e.g. comment) is +being set without qualifiers, all existing frames of this type will be +removed and replaced with a new one. Its qualifiers will be set to +default values. @@ -445,2 +449,36 @@ $ idest --latin1 --set artist='Llu@'is Llach' *.mp3 +@node Copy +@chapter Copying Tags Between Files +@xopindex{copy, described} + To copy tags from one file to another, use the @option{--copy} +(@option{-c}) option. Its argument supplies the @dfn{source file}. +Non-optional arguments supply destination files: + +@example +$ idest --copy sample.mp3 track1.mp3 track2.mp3 +@end example + +As a result of this operation all tags from @file{sample.mp3} will be +copied to @file{track1.mp3} and @file{track2.mp3}. + +@anchor{filter--copy} +@xopindex{--filter, used with @option{--copy}}. +As with another operations, you can abridge the scope of copying to +a certain subset of frames by using the @option{--filter} option, +e.g.: + +@example +$ idest --copy sample.mp3 --filter TPE1,TCOM track1.mp3 track2.mp3 +@end example + +You can also use @option{--copy} together with @option{--set} in a +single invocation. In this case, the frames will first be copied from +the source file and then the resulting tags will be modified according +to the @option{--set} options. For example: + +@example +$ idest --copy sample.mp3 --filter TPE1,TCOM \ + --set year=2003 track1.mp3 track2.mp3 +@end example + @node Delete @@ -460,3 +498,4 @@ with caution. -@xopindex{filter, used with --delete} +@anchor{filter--delete} +@xopindex{filter, used with @option{--delete}} A list of frame names can be given either with the @option{--filter} @@ -485,2 +524,5 @@ $ idest --delete --filter=comment::Bit_Rate track01.mp3 +The same applies to other frames that can appear multiple times +(@pxref{Frames}). + @node ID Versioning @@ -544,3 +586,3 @@ file: jt_lluny.mp3 ntags: 2 -version: 24.0 +version: 2.4.0 offset: 0 @@ -555,6 +597,5 @@ ID3 tags in it. Following are tag descriptions formatted as three values for each tag. The @samp{version} line shows the tag version -(major and minor numbers, separated by a dot). The major number greater -than 1 means it is a ID3v2 tag. The @samp{offset} line shows the -offset of this tag in the file, and the @samp{length} line contains -size of this tag in bytes. +(major and minor numbers, separated by dots). The @samp{offset} line +shows the offset of this tag in the file, and the @samp{length} line +contains size of this tag in bytes. @@ -585,2 +626,5 @@ $ idest --script list.scm *.mp3 +You can omit the @samp{.scm} suffix, as @command{idest} will try it +automatically (see below). + When this option is given, the following operations are performed: @@ -623,2 +667,8 @@ the default value of @code{%load-path}. +The script is loaded via @code{primitive-load-path} (@pxref{Loading,, +primitive-load-path,guile,The Guile Reference Manual}), so +@command{idest} will consult the @code{%load-extensions} list and +try suffixes from that list as described in +@ref{Loading,,%load-extensions,guile,The Guile Reference Manual}). + @item @@ -630,5 +680,6 @@ Environment,,command-line,guile,The Guile Reference Manual}). It can also modify the argument list (e.g. by removing its command -line options). Any changes it does to the argument list become -visible to @command{idest}. The only requirement is that the modified -argument list must contain only input file names. +line options). It must not, however, modify @samp{argv[0]}. Any +changes it does to the argument list become visible to +@command{idest}. The only requirement is that the modified argument +list consist of the script name (as argv[0]) and input file names. @@ -665,8 +716,27 @@ These are the same descriptions that are output with the +@item rawdata +Unsupported or partially-supported frames contain only this property. +Its value is a list of frame fields. Each field is represented by a +triplet @samp{(@var{ord} @var{type} @var{value})}, where @var{ord} is the +ordinal number of that field in frame, @var{type} is its type (integer) and +@var{value} is its value. If @var{type} is one of numeric types, +@var{value} is the numeric value converted to string (as per +@code{number->string}). If @var{type} is a string type, @var{value} +contains the string in the appropriate encoding. Otherwise, +@var{value} holds the field value as a binary string. Each byte in +such a string is represented by two hexadecimal digits. For example, +@samp{AB\n} is represented as @samp{41420A}. +@end table + +More properties are defined at a per-frame basis to represent +frame qualifiers. They are named after corresponding qualifiers +as listed in @code{--list-frames} output (@pxref{describe}). For +example, for @samp{comment} (@samp{COMM}) frames: + +@table @asis @item lang A three-letter code of the language in which the text is written. -This property is present only in comment fields. @item condesc -Content descriptor. This property is present only in comment fields. +Content descriptor. @end table @@ -688,7 +758,10 @@ to modify any frames, it must return @code{#f}. -The two following sections show how to write script files. +The two following sections show how to write script files. The +sample scripts they discuss can be found in subdirectory +@file{examples} of the @command{idest} distribution. @menu -* list.scm:: Using Scripts to List ID3 Frames -* title.scm:: Using Scripts to Modify ID3 Frames +* list.scm:: Using Scripts to List ID3 Frames +* settitle.scm:: Using Scripts to Modify ID3 Frames +* dry-run:: Testing Scripts @end menu @@ -705,3 +778,3 @@ listing the contents of ID3 tags. ;; list1.scm -- lists all frames. -(define (idest-main name tags) +(define (idest-main name frames) (display name) @@ -709,6 +782,6 @@ listing the contents of ID3 tags. (for-each - (lambda (tag) - (display tag) + (lambda (frame) + (display frame) (newline)) - tags)) + frames)) @end lisp @@ -740,3 +813,3 @@ frame: @lisp -(define (idest-main name tags) +(define (idest-main name frames) (display name) @@ -744,8 +817,8 @@ frame: (for-each - (lambda (tag) - (if (member (car tag) frame-list) + (lambda (frame) + (if (member (car frame) frame-list) (begin - (display tag) + (display frame) (newline)))) - tags)) + frames)) @end lisp @@ -761,3 +834,3 @@ script itself, and it should not be modified. ((< (length cmd) 3) - (error "usage: list2.scm FRAME-LIST FILE...") + (error "usage: idest -S list2 FRAME-LIST FILE...") (exit 1)) @@ -774,3 +847,3 @@ The full script text is then: -(define (idest-main name tags) +(define (idest-main name frames) (display name) @@ -778,8 +851,8 @@ The full script text is then: (for-each - (lambda (tag) - (if (member (car tag) frame-list) + (lambda (frame) + (if (member (car frame) frame-list) (begin - (display tag) + (display frame) (newline)))) - tags)) + frames)) @@ -788,3 +861,3 @@ The full script text is then: ((< (length cmd) 3) - (error "usage: list2.scm FRAME-LIST FILE...") + (error "usage: idest -S list2 FRAME-LIST FILE...") (exit 1)) @@ -798,3 +871,3 @@ Sample usage: @example -$ idest --script list2.scm TIT2,TENC track01.scm +$ idest --script list2 TIT2,TENC track01.scm (TIT2 (descr . Title/songname/content description) (text . Cor i arbre)) @@ -807,3 +880,3 @@ followed by the title, artist name and year, as shown in this sample output: @example -$ idest -S shortlist.scm *.mp3 +$ idest -S shortlist *.mp3 dnr.mp3: Diamonds & Rust by Joan Baez, 1975 @@ -840,3 +913,3 @@ Now, we define the main function: -@node title.scm +@node settitle.scm @section Using Scripts to Modify ID3 Frames @@ -856,3 +929,3 @@ created using the following algorithm: @lisp -;; title.scm - set title (TIT2) frame based on the file name. +;; settitle.scm - set title (TIT2) frame based on the file name. @@ -867,6 +940,9 @@ created using the following algorithm: (cons "TIT2" - (string-map - (lambda (c) - (if (char=? c #\_) #\space c)) - (match:substring match 1))) + (list + (cons + 'text + (string-map + (lambda (c) + (if (char=? c #\_) #\space c)) + (match:substring match 1))))) ;; @@ -885,5 +961,70 @@ created using the following algorithm: @example -$ idest --script title.scm *.mp3 +$ idest --script settitle *.mp3 @end example +@node dry-run +@section Testing Scripts +@cindex dry-run +@cindex test mode + When writing a script which modifies tags, it is good idea to test +it before applying it to your data. @command{Idest} provides a +mechanism for that. To see what your script would do without actually +modifying your data, insert the word @samp{dry-run} between the +@option{--script} (or @option{-S}) option and the script name in the +program invocation, e.g.: + +@example +$ idest --script dry-run settitle *.mp3 +@end example + + This will run your script as usual, but instead of applying the +changes to the input files, @command{idest} will verbosely print +results of each invocation of @samp{idest-main}. Input files will +then be opened in read-only mode. + + Here is an example of the dry-run output, obtained from the command +above: + +@example +dry-run: loading ../examples/settitle.scm ... +dry-run: loading /usr/share/guile/1.8/ice-9/regex.scm ... +dry-run: loading /usr/share/guile/1.8/srfi/srfi-13.scm ... +File Tinc_un_clavell_per_a_tu.mp3 +(TIT2 (text . Tinc un clavell per a tu)) +(TALB (descr . Album/movie/show title) (text . Maremar)) +... +@end example + +The first frame shown (@samp{TIT2}) was produced by +@file{settitle.scm} (see the previous chapter). Rest of frames come +from the input file itself. + +Notice the diagnostics lines which start with @samp{dry-run}. In +dry-run mode @command{idest} verbosely reports the full file names of +all files it loads. In this particular case, the line + +@example +dry-run: loading ../examples/settitle.scm ... +@end example + +@noindent +shows the full path of the script file itself, whereas the two lines + +@example +dry-run: loading /usr/share/guile/1.8/ice-9/regex.scm ... +dry-run: loading /usr/share/guile/1.8/srfi/srfi-13.scm ... +@end example + +@noindent +reflect the @code{use-modules} clause at the beginning of +@file{settitle.scm} (@pxref{settitle.scm}). + +@subheading Implementation note +@findex dry-run.scm +The @samp{dry-run} mode is actually implemented as a usual +@command{idest} Guile script, named @file{dry-run.scm}. The +script is installed to the package script directory. Its +source can be found in the subdirectory @file{example} of the +@command{idest} distribution. + @node Backups @@ -895,3 +1036,3 @@ $ idest --script title.scm *.mp3 modifying them. Two ways of creating backup copies are supported. -Firstly, backups may be made by copying the file to another file +First, backups may be made by copying the file to another file before modifying it. This backup method is enabled using the @@ -992,2 +1133,6 @@ numbers. +@item -c @var{file} +@item --copy=@var{file} +Copy tags from @var{file} to destination files. @xref{Copy}. + @item -d[@var{flist}] @@ -1007,2 +1152,10 @@ Guile function to call. @xref{Scripting}. +@item -F @var{flist} +@itemx --filter=@var{flist} +Operate only on frames from @var{flist}. This option affects the +following options: @option{--copy} (@pxref{filter--copy, filter in +copy mode}), @option{--query} (@pxref{filter--query, filter in query +mode}), @option{--delete} (@pxref{filter--delete, filter in delete +mode}) and @option{--list-frames} (@pxref{filter--list-frames}). + @item -h @@ -1020,2 +1173,6 @@ Store strings in ISO-8859-1 encoding, when used with @option{--set} +@item -L +@item --list-frames +List the supported ID3v2 frames. @xref{list-frames}. + @item -q[@var{flist}] @@ -1210 +1367,2 @@ This is a general index of all issues discussed in this manual. @bye + diff --git a/examples/Makefile.am b/examples/Makefile.am index 872a970..73b4717 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -18,2 +18,3 @@ EXTRA_DIST = \ delcomm.scm\ + dry-run.scm\ list1.scm\ @@ -21,6 +22,6 @@ EXTRA_DIST = \ shortlist.scm\ - title.scm + settitle.scm sitedir = @GUILE_SITE@/$(PACKAGE) -site_DATA=echo.scm +site_DATA=dry-run.scm diff --git a/examples/dry-run.scm b/examples/dry-run.scm index d6b07ab..637ad8c 100644 --- a/examples/dry-run.scm +++ b/examples/dry-run.scm @@ -1,2 +1,2 @@ -;; echo.scm - test another Idest script. +;; dry-run.scm - run a script and show the frames it produces. ;; Copyright (C) 2011 Sergey Poznyakoff @@ -35,3 +35,13 @@ (let ((result (main-func file frames))) - (format #t "File ~A ~A~%" file result)))))) + (format #t "File ~A~%" file) + (cond + ((not result) + (format #t "No modifications~%")) + ((null? result) + (format #t "Would delete all frames~%")) + (else + (for-each (lambda (frame) + (display frame) + (newline)) + result)))))))) (else diff --git a/examples/settitle.scm b/examples/settitle.scm index e541b66..cd43106 100644 --- a/examples/settitle.scm +++ b/examples/settitle.scm @@ -16,6 +16,9 @@ (cons "TIT2" - (string-map - (lambda (c) - (if (char=? c #\_) #\space c)) - (match:substring match 1))) + (list + (cons + 'text + (string-map + (lambda (c) + (if (char=? c #\_) #\space c)) + (match:substring match 1))))) ;; diff --git a/src/cmdline.opt b/src/cmdline.opt index 1400d2c..36478f0 100644 --- a/src/cmdline.opt +++ b/src/cmdline.opt @@ -114,3 +114,3 @@ GROUP([<Operation modifiers>]) OPTION(filter,F,FRAME-LIST, - [<with --query, --copy and --delete: operate only on matching frames>]) + [<operate only on matching frames>]) BEGIN |