#!/usr/bin/env python
from setuptools import setup
setup(
  name = 'cs.fstags',
  description = 'Simple filesystem based file tagging and the associated `fstags` command line script.',
  author = 'Cameron Simpson',
  author_email = 'cs@cskk.id.au',
  version = '20200229',
  url = 'https://bitbucket.org/cameron_simpson/css/commits/all',
  classifiers = ['Programming Language :: Python', 'Programming Language :: Python :: 3', 'Development Status :: 4 - Beta', 'Intended Audience :: Developers', 'Operating System :: OS Independent', 'Topic :: Software Development :: Libraries :: Python Modules', 'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)'],
  entry_points = {'console_scripts': ['fstags = cs.fstags:main']},
  include_package_data = True,
  install_requires = ['cs.cmdutils', 'cs.context', 'cs.deco', 'cs.edit', 'cs.lex', 'cs.logutils', 'cs.pfx', 'cs.resources', 'cs.tagset', 'cs.threads', 'cs.upd', 'icontract'],
  keywords = ['python3'],
  license = 'GNU General Public License v3 or later (GPLv3+)',
  long_description = '*Latest release 20200229*:\nNew TaggedPath.modified property aliasing the TagSet.modified attribute.\nls: new -d option to treat directories like files (do not recurse), aiding reporting of tags for a directory.\nfind,ls subcommands: work off the realpath of the supplied top level path.\nTag: now subclasses namedtuple.\nRewrite rpaths() to use scandir and to also yield (is_dir,path) tuples.\nTagSet, Tag, TagChoice moved into new cs.tagset module for reuse.\njson_import: make --prefix mandatory, is "." as separator if not empty.\nMove filename regexp rules to [filename_rules] config section.\nNew CascadeRule for representing a "target_tag_name = tag_name1 tag_name2..." config rules.\nautotag: include the cascade rules in the autotagging after the filename rules.\n\nSimple filesystem based file tagging\nand the associated `fstags` command line script.\n\nWhy `fstags`?\nBy storing the tags in a separate file we:\n* can store tags without modifying a file\n* do no need to know the file\'s format,\n  whether that supports metadata or not\n* can process tags on any kind of file\n* because tags are inherited from parent directories,\n  tags can be automatically acquired merely by arranging your file tree\n\nTags are stored in the file `.fstags` in each directory;\nthere is a line for each entry in the directory with tags\nconsisting of the directory entry name and the associated tags.\n\nTags may be "bare", or have a value.\nIf there is a value it is expressed with an equals (`\'=\'`)\nfollowed by the JSON encoding of the value.\n\nThe tags for a file are the union of its direct tags\nand all relevant ancestor tags,\nwith priority given to tags closer to the file.\n\nFor example, a media file for a television episode with the pathname\n`/path/to/series-name/season-02/episode-name--s02e03--something.mp4`\nmight obtain the tags:\n\n    series.title="Series Full Name"\n    season=2\n    sf\n    episode=3\n    episode.title="Full Episode Title"\n\nfrom the following `.fstags` entries:\n* tag file `/path/to/.fstags`:\n  `series-name sf series.title="Series Full Name"`\n* tag file `/path/to/series-name/.fstags`:\n  `season-02 season=2`\n* tag file `/path/to/series-name/season-02/.fstags`:\n  `episode-name--s02e03--something.mp4 episode=3 episode.title="Full Episode Title"`\n\n## Class `CascadeRule`\n\nA cascade rule of possible source tag names to provide a target tag.\n\n## Class `FSTags(cs.resources.MultiOpenMixin)`\n\nA class to examine filesystem tags.\n\n## Class `FSTagsCommand(cs.cmdutils.BaseCommand)`\n\n`fstags` main command line class.\n\n\nCommand line usage:\n\n    Usage:\n        FSTagsCommand autotag paths...\n            Tag paths based on rules from the rc file.\n        FSTagsCommand cp [-fnv] srcpath dstpath\n        FSTagsCommand cp [-fnv] srcpaths... dstdirpath\n            Copy files and their tags into targetdir.\n            -f  Force: remove destination if it exists.\n            -n  No remove: fail if the destination exists.\n            -v  Verbose: show copied files.\n        FSTagsCommand scrub paths...\n            Remove all tags for missing paths.\n            If a path is a directory, scrub the immediate paths in the directory.\n        FSTagsCommand find [--for-rsync] path {tag[=value]|-tag}...\n            List files from path matching all the constraints.\n            -d          treat directories like files (do no recurse).\n            --direct    Use direct tags instead of all tags.\n            --for-rsync Instead of listing matching paths, emit a\n                        sequence of rsync(1) patterns suitable for use with\n                        --include-from in order to do a selective rsync of the\n                        matched paths.\n            -o output_format\n                        Use output_format as a Python format string to lay out\n                        the listing.\n                        Default: {filepath}\n        FSTagsCommand json_import --prefix=tag_prefix {-|path} {-|tags.json}\n            Apply JSON data to path.\n            A path named "-" indicates that paths should be read from\n            the standard input.\n            The JSON tag data come from the file "tags.json"; the name\n            "-" indicates that the JSON data should be read from the\n            standard input.\n        FSTagsCommand ln [-fnv] srcpath dstpath\n        FSTagsCommand ln [-fnv] srcpaths... dstdirpath\n            Link files and their tags into targetdir.\n            -f  Force: remove destination if it exists.\n            -n  No remove: fail if the destination exists.\n            -v  Verbose: show linked files.\n        FSTagsCommand ls [--direct] [-o output_format] [paths...]\n            List files from paths and their tags.\n            --direct    List direct tags instead of all tags.\n            -o output_format\n                        Use output_format as a Python format string to lay out\n                        the listing.\n                        Default: {filepath_encoded} {tags}\n        FSTagsCommand mv [-fnv] srcpath dstpath\n        FSTagsCommand mv [-fnv] srcpaths... dstdirpath\n            Move files and their tags into targetdir.\n            -f  Force: remove destination if it exists.\n            -n  No remove: fail if the destination exists.\n            -v  Verbose: show moved files.\n        FSTagsCommand tag {-|path} {tag[=value]|-tag}...\n            Associate tags with a path.\n            With the form "-tag", remove the tag from the immediate tags.\n            A path named "-" indicates that paths should be read from the\n            standard input.\n        FSTagsCommand tagpaths {tag[=value]|-tag} {-|paths...}\n            Associate a tag with multiple paths.\n            With the form "-tag", remove the tag from the immediate tags.\n            A single path named "-" indicates that paths should be read\n            from the standard input.\n        FSTagsCommand test [--direct] path {tag[=value]|-tag}...\n            Test whether the path matches all the constraints.\n            --direct    Use direct tags instead of all tags.\n        FSTagsCommand xattr_import {-|paths...}\n            Import tag information from extended attributes.\n        FSTagsCommand xattr_export {-|paths...}\n            Update extended attributes from tags.\n\n## Class `FSTagsConfig`\n\nA configuration for fstags.\n\n### Method `FSTagsConfig.__init__(self, rcfilepath=None)`\n\nInitialise the config.\n\nParameters:\n* `rcfilepath`: the path to the confguration file\n  If `None`, default to `\'~/.fstagsrc\'` (from `RCFILE`).\n\n## Function `get_xattr_value(filepath, xattr_name)`\n\nRead the extended attribute `xattr_name` of `filepath`.\nReturn the extended attribute value as a string,\nor `None` if the attribute does not exist.\n\nParameters:\n* `filepath`: the filesystem path to update\n* `xattr_name`: the extended attribute to obtain\n  if this is a `str`, the attribute is the UTF-8 encoding of that name.\n\n## Class `HasFSTagsMixin`\n\nMixin providing a `.fstags` property.\n\n## Function `main(argv=None)`\n\nCommand line mode.\n\n## Class `RegexpTagRule`\n\nA regular expression based `Tag` rule.\n\n## Function `rfilepaths(path, name_selector=None, U=None)`\n\nGenerator yielding pathnames of files found under `path`.\n\n## Function `rpaths(path, *, yield_dirs=False, name_selector=None, U=None)`\n\nRecurse over `path`, yielding `(is_dir,subpath)`\nfor all selected subpaths.\n\n## Function `rsync_patterns(paths, top_path)`\n\nReturn a list of rsync include lines\nsuitable for use with the `--include-from` option.\n\n## Class `TagFile(HasFSTagsMixin)`\n\nA reference to a specific file containing tags.\n\nThis manages a mapping of `name` => `TagSet`,\nitself a mapping of tag name => tag value.\n\n## Class `TagFileEntry(builtins.tuple)`\n\nTagFileEntry(tagfile, name)\n\n## Class `TaggedPath(HasFSTagsMixin)`\n\nClass to manipulate the tags for a specific path.\n\n## Function `update_xattr_value(filepath, xattr_name, new_xattr_value)`\n\nUpdate the extended attributes of `filepath`\nwith `new_xattr_value` for `xattr_name`.\nReturn the previous value, or `None` if the attribute was missing.\n\nWe avoid calling `os.setxattr` if the value will not change.\n\nParameters:\n* `filepath`: the filesystem path to update\n* `xattr_name`: the extended attribute to update;\n  if this is a `str`, the attribute is the UTF-8 encoding of that name.\n* `new_xattr_value`: the new extended attribute value, a `str`\n  which should be the transcription of `TagSet`\n  i.e. `str(tagset)`\n\n## Function `verbose(msg, *a)`\n\nEmit message if in verbose mode.\n\n\n\n# Release Log\n\n*Release 20200229*:\nNew TaggedPath.modified property aliasing the TagSet.modified attribute.\nls: new -d option to treat directories like files (do not recurse), aiding reporting of tags for a directory.\nfind,ls subcommands: work off the realpath of the supplied top level path.\nTag: now subclasses namedtuple.\nRewrite rpaths() to use scandir and to also yield (is_dir,path) tuples.\nTagSet, Tag, TagChoice moved into new cs.tagset module for reuse.\njson_import: make --prefix mandatory, is "." as separator if not empty.\nMove filename regexp rules to [filename_rules] config section.\nNew CascadeRule for representing a "target_tag_name = tag_name1 tag_name2..." config rules.\nautotag: include the cascade rules in the autotagging after the filename rules.\n\n*Release 20200210*:\nNew "json_import" subcommand to import a JSON dict as tags, initial use case to load the metadata from youtube-dl.\nNew "scrub" command line operation, to purge tags of paths which do not exist.\nNew "cp", "ln" and "mv" subcommands to copy/link/move paths and take their tags with them.\nNew "test" subcommand to test paths against tag criteria, useful for find and scripts.\nSmall bugfixes.\n\n*Release 20200130*:\nNew FSTagsConfig class which parses the .fstagsrc as a .ini file; related adjustments.\nNew HasFSTagsMixin presenting a settable .fstags property with a shared default.\nNew xattr_import and xattr_export subcommands, remove implicit xattr access/update from other operations.\nNew TagSet.__len__ returning the number of tags.\nAdd "-" support for stdin to "tag" and "tagpaths" subcommands.\n\n*Release 20200113.2*:\nFSTagsCommand docstring tweak.\n\n*Release 20200113.1*:\nSmall docstring updates.\n\n*Release 20200113*:\nMirror tags to user.cs.fstags xattr to honour Linux namespace requirements. Add "filesize" to available tag string format (-o option). Small bugfixes.\n\n*Release 20191230*:\nCommand line: new "find" command to search a file tree based on tags.\nCommand line: new "mv" command to move a file and its tags.\nCommand line: Python string formats for "find" and "ls" output.\nTaggedPath.autotag: new optional `no_save` parameter, default False, to suppress update of the associated .fstags file.\nInital and untested "mirror tags to xattrs" support.\n\n*Release 20191201*:\nNew "edit" subcommand to rename files and edit tags.\n\n*Release 20191130.1*:\nInitial release: fstags, filesystem based tagging utility.',
  long_description_content_type = 'text/markdown',
  package_dir = {'': 'lib/python'},
  py_modules = ['cs.fstags'],
)
