{"id":20425299,"url":"https://github.com/catseye/tagfarm","last_synced_at":"2025-06-13T06:08:19.349Z","repository":{"id":52204280,"uuid":"256468297","full_name":"catseye/tagfarm","owner":"catseye","description":"MIRROR of https://codeberg.org/catseye/tagfarm : An ultra-lightweight filesystem-based categorization system for arbitrary files","archived":false,"fork":false,"pushed_at":"2023-10-27T08:33:34.000Z","size":61,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-13T06:07:42.868Z","etag":null,"topics":["categorization","link-farm","media-categories","tagging-tool"],"latest_commit_sha":null,"homepage":"https://catseye.tc/node/tagfarm","language":"Python","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/catseye.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-04-17T10:07:32.000Z","updated_at":"2023-10-26T20:42:34.000Z","dependencies_parsed_at":"2025-01-15T15:08:41.583Z","dependency_job_id":"f89f81d9-069c-4403-98c5-5691e4a31454","html_url":"https://github.com/catseye/tagfarm","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/catseye/tagfarm","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/catseye%2Ftagfarm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/catseye%2Ftagfarm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/catseye%2Ftagfarm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/catseye%2Ftagfarm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/catseye","download_url":"https://codeload.github.com/catseye/tagfarm/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/catseye%2Ftagfarm/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259592261,"owners_count":22881267,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["categorization","link-farm","media-categories","tagging-tool"],"created_at":"2024-11-15T07:12:49.177Z","updated_at":"2025-06-13T06:08:19.073Z","avatar_url":"https://github.com/catseye.png","language":"Python","readme":"`tagfarm`\n=========\n\n_Version 0.3_\n| _Entry_ [@ catseye.tc](https://catseye.tc/node/tagfarm)\n| _See also:_ [shelf](https://codeberg.org/catseye/shelf#shelf)\n∘ [ellsync](https://codeberg.org/catseye/ellsync#ellsync)\n∘ [yastasoti](https://codeberg.org/catseye/yastasoti#yastasoti)\n\n- - - -\n\n\u003cimg align=\"right\" src=\"images/tagfarm-logo.png?raw=true\" /\u003e\n\n**tagfarm** is an ultra-lightweight filesystem-based categorization system for arbitrary files.\n\nMotivation\n----------\n\nThe limitation of a hierarchical filesystem is that any one file can only reside in one\ndirectory.  But most files are best described by classifying them in more than one\ncategory.  So directories don't map very well to categories -- if you have a picture of\nthe Mona Lisa, should you put it in `Portraits` or `Works by Leonardo da Vinci` or\n`Enigmatic Smiles`?\n\nThe solution on blogs and wikis is to use \"tags\" or \"categories\", to allow every page\nto be tagged with zero or more tags, and to allow all pages with a given tag to be listed\nin a \"tag index\" or \"category page\".\n\ntagfarm implements the same idea on a local filesystem.  Each tag is implemented as a\ndirectory containing symbolic links to the files that have that tag.  And this is *all*\nit consists of.\n\nThere are several advantages to this.  There's no metadata to go out of sync, no database\nengine to install and maintain.  When you move files around, you can just run\n`tagfarm repair` to rewrite the tag links.  You can treat the tag links as you would any\nother file — for example, you can remove a tag from a file just by deleting the tag link.\n\nThere are also some disadvantages, of course.  Primarily, any limitations that your\nfilesystem has are also going to be imposed on the categorization system.  So, for\nexample, if your OS has performance problems listing 10,000 files in a single directory,\nthe same would hold for a set of 10,000 files that are tagged with the same tag.\n\nQuick start\n-----------\n\nMake sure you have Python (2.7 or 3.x) installed, clone this repository, and put its `bin`\ndirectory on your executable search path.  You can then run `tagfarm` from your terminal.\n\nOverview\n--------\n\n### Media tree\n\n`tagfarm` operates on a part of your filesystem it calls the *media tree*.  There may be\nmultiple media trees in your filesystem.  The topmost directory of a media tree is called\nthe *media root* and it is identified by having a directory\ncalled `by-tag` in it.  When `tagfarm` is started, it finds the media root it will operate\non, by looking for the `by-tag` directory, first in the current directory, then in every\nsuccessive parent directory thereof.  If it reaches `/` without having found a `by-tag`\ndirectory, it exits immediately with an error code.\n\nOne constraint that applies to the media tree is that every file in it should have a\nunique name.  This allows `tagfarm repair` to recreate fix broken tag links when a file is\nmoved around inside the media tree.\n\n### `tag` and `untag`\n\nYou can add a tag to one or more files with the command\n\n    tagfarm tag \u003ctagname\u003e \u003cfilename\u003e [\u003cfilename2\u003e...]\n\nYou can then list the contents of `by-tag/\u003ctagname\u003e` and see there are symlinks there.\n\nYou can remove a tag to one or more files with the command\n\n    tagfarm untag \u003ctagname\u003e \u003cfilename\u003e [\u003cfilename2\u003e...]\n\n### `showtags`\n\nYou can list the tags that have been applied to one or more files with\n\n    tagfarm showtags \u003cfilename\u003e [\u003cfilename2\u003e...]\n\n### `repair`\n\nIf the source files are moved around, the symbolic links will break.  Assuming the\nfiles, after having moved, have not changed names and are still found somewhere in\nthe media tree, tagfarm can repair the broken links with the command\n\n    tagfarm repair\n\nBy default, tagfarm will only attempt to repair broken links if they are actually\nsymlinks (not, for example, regular files) and not broken.  To have it replace all files\nit happens to find in the tag link directory, pass `--force-relink`.  This is occasionally\nhandy for converting a directory full of copies of elsewhere-existing media files,\ninto links.  In conjunction with this, `--restrict-to-tag` may be used to name a single tag,\nand this operation will be applied only to that tag.\n\n`tagfarm repair` will also replace any links it finds that have absolute target paths,\nwith ones with relative target paths, even when the link is not broken.\n\n`tagfarm repair` will also, when processing a link whose name is like `Link to xyz`,\nrename it to simply `xyz`.  This is to handle the case where links are manually\ncreated in a tag directory using a tools such as Nautilus (Gnome Desktop).\n\n### `rename`\n\n    tagfarm rename \u003coldfilename\u003e \u003cnewfilename\u003e\n\nRenames the file, like `mv`, but also updates any tags that might be on it.\n\n### `collect`\n\n    tagfarm collect \u003ctagname\u003e \u003cdestdir\u003e\n\nConvenience command to move all the files with a given tag into a destination directory.\nIf the destination directory does not yet exist, will be created.  The tags of the files\nare not changed.  At the end, `tagfarm repair` is called to update the tag links.\n\nOther operations\n----------------\n\nThe advantage of tagfarm being ultra-lightweight is that if there is something that\nit does not directly support, it's often easy to accomplish it by simply issuing\nsome conventional commands to alter the filesystem.  For this reason, some\nfunctionalities you might expect to exist, don't have specific `tagfarm` commands\nimplemented for them.\n\nFor example, to rename a tag, one needs only to rename the directory that contains\nthe tag links.  For example:\n\n    mv by-tag/airplane by-tag/aeroplane\n\nTODO\n----\n\nBetter handling of cases where the target being linked is itself a link.\n\nSet-theoretic queries on tags (e.g. tag all files with X or Y and not Z with a new tag T).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcatseye%2Ftagfarm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcatseye%2Ftagfarm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcatseye%2Ftagfarm/lists"}