text: # -*- coding: utf-8 -*-
  # Copyright 2014 Marcus Sundman
  #
  # This program is free software; you can redistribute it and/or modify
  # it under the terms of the GNU General Public License as published by
  # the Free Software Foundation; either version 2 of the License, or
  # (at your option) any later version.
  
  """A program replicating the functionality of id3lib's id3cp, using mutagen for
  tag loading and saving.
  """
  
  import sys
  import os.path
  
  import mutagen
  import mutagen.id3
  from mutagen._senf import print_, argv
  
  from ._util import SignalHandler, OptionParser
  
  
  VERSION = (0, 1)
  _sig = SignalHandler()
  
  
  def printerr(*args, **kwargs):
      kwargs.setdefault("file", sys.stderr)
      print_(*args, **kwargs)
  
  
  class ID3OptionParser(OptionParser):
      def __init__(self):
          mutagen_version = mutagen.version_string
          my_version = ".".join(map(str, VERSION))
          version = "mid3cp %s\nUses Mutagen %s" % (my_version, mutagen_version)
          self.disable_interspersed_args()
          OptionParser.__init__(
              self, version=version,
              usage="%prog [option(s)] <src> <dst>",
              description=("Copies ID3 tags from <src> to <dst>. Mutagen-based "
                           "replacement for id3lib's id3cp."))
  
  
  def copy(src, dst, merge, write_v1=True, excluded_tags=None, verbose=False):
      """Returns 0 on success"""
  
      if excluded_tags is None:
          excluded_tags = []
  
      try:
          id3 = mutagen.id3.ID3(src, translate=False)
      except mutagen.id3.ID3NoHeaderError:
          print_(u"No ID3 header found in ", src, file=sys.stderr)
          return 1
      except Exception as err:
          print_(str(err), file=sys.stderr)
          return 1
  
      if verbose:
          print_(u"File", src, u"contains:", file=sys.stderr)
          print_(id3.pprint(), file=sys.stderr)
  
      for tag in excluded_tags:
          id3.delall(tag)
  
      if merge:
          try:
              target = mutagen.id3.ID3(dst, translate=False)
          except mutagen.id3.ID3NoHeaderError:
              # no need to merge
              pass
          except Exception as err:
              print_(str(err), file=sys.stderr)
              return 1
          else:
              for frame in id3.values():
                  target.add(frame)
  
              id3 = target
  
      # if the source is 2.3 save it as 2.3
      if id3.version < (2, 4, 0):
          id3.update_to_v23()
          v2_version = 3
      else:
          id3.update_to_v24()
          v2_version = 4
  
      try:
          id3.save(dst, v1=(2 if write_v1 else 0), v2_version=v2_version)
      except Exception as err:
          print_(u"Error saving", dst, u":\n%s" % str(err),
                 file=sys.stderr)
          return 1
      else:
          if verbose:
              print_(u"Successfully saved", dst, file=sys.stderr)
          return 0
  
  
  def main(argv):
      parser = ID3OptionParser()
      parser.add_option("-v", "--verbose", action="store_true", dest="verbose",
                        help="print out saved tags", default=False)
      parser.add_option("--write-v1", action="store_true", dest="write_v1",
                        default=False, help="write id3v1 tags")
      parser.add_option("-x", "--exclude-tag", metavar="TAG", action="append",
                        dest="x", help="exclude the specified tag", default=[])
      parser.add_option("--merge", action="store_true",
                        help="Copy over frames instead of the whole ID3 tag",
                        default=False)
      (options, args) = parser.parse_args(argv[1:])
  
      if len(args) != 2:
          parser.print_help(file=sys.stderr)
          return 1
  
      (src, dst) = args
  
      if not os.path.isfile(src):
          print_(u"File not found:", src, file=sys.stderr)
          parser.print_help(file=sys.stderr)
          return 1
  
      if not os.path.isfile(dst):
          printerr(u"File not found:", dst, file=sys.stderr)
          parser.print_help(file=sys.stderr)
          return 1
  
      # Strip tags - "-x FOO" adds whitespace at the beginning of the tag name
      excluded_tags = [x.strip() for x in options.x]
  
      with _sig.block():
          return copy(src, dst, options.merge, options.write_v1, excluded_tags,
                      options.verbose)
  
  
  def entry_point():
      _sig.init()
      return main(argv)
  