# Nielsen
Nielsen helps rename and organize digital media collections.
Consider a filename such as `The.Wheel.of.Time.S01E06.720p.WEB.x265-MiNX.mkv`.
If you'd prefer something more along the lines of `The Wheel of Time -01.06-
The Flame of Tar Valon.mkv`, Nielsen can help.
Nielsen endeavors to automatically handle these types of renaming operations,
as well as move the files into a more hierarchical folder structure that keeps
your media directories tidy.
## Requirements
- Python 3.12 (or newer)
- [Poetry][poetry] (for source installations)
## Install
### PyPI
This package is published on [PyPI][pypi-nielsen] and can be installed from
there with the following command.
```bash
pip install nielsen
```
### Source
This package can also be installed from source by cloning this repository and
using [Poetry][poetry].
```bash
poetry install
```
## Concepts
- [`Media`](./ARCHITECTURE.md#nielsenmediamedia) - Represents a file on disk
and its metadata. The specific subclass determines how metadata is inferred
and which `Fetcher` should be used.
- [`Fetcher`](./ARCHITECTURE.md#nielsenfetcherfetcher) - Queries external
systems/services for metadata about a given `Media` instance.
- [`Processor`](./ARCHITECTURE.md#nielsenprocessorprocessor) - A grouping of
a `MediaType` and `Fetcher`. Given a file, the `Processor` creates the
appropriate `Media` (based on the `MediaType`) and `Fetcher` to query for
metadata.
Under the hood, "processing" a file will create a `Media` object from the given
path and `MediaType`, infer metadata based on the filename (e.g. TV series
name, season number, episode number, and episode title).
If the `fetch` option is enabled, then a `Fetcher` will also be created to
query more information (e.g. `Ted.Lasso.S01.E01.mp4` doesn't give us an episode
title, but the `Fetcher` can ask [TVMaze][tvmaze] for it).
`nielsen` can then rename the file (e.g. `Ted Lasso -01.04- For the
Children.mp4`) and move it to your media library (e.g. `~/Videos/TV/Ted
Lasso/Season 01/`).
See the [ARCHITECTURE][architecture] file for more detailed information.
## Usage
The primary use case `nielsen` is intended to handle is that of renaming a file
and moving it into the correct location on disk. This is done with the
`process` subcommand.
All commands (and subcommands) will accept a `--help` flag to provide more
information about usage.
```bash
# Process a given file
nielsen process PATH_TO_FILE
# See a list of all subcommands
nielsen --help
```
### `tv` subcommand
The `tv` subcommand can be used to make some simple queries to TVMaze and to
apply the results of those queries to files on-demand.
#### `nielsen tv fetch`
The `tv fetch` subcommand queries the TVMaze API. The more information you
provide, the more specific the results. You can fetch information about a
series, a season, or an episode.
```bash
# Get information about a series
nielsen tv fetch --series "Ted Lasso"
# Get information about a specific season of a series
nielsen tv fetch --series "Ted Lasso" --season 2
# Get information about a specific episode of a season of a series
nielsen tv fetch --series "Ted Lasso" --season 2 --episode 5
```
Additionally, the `--raw` flag can be used with any of the commands above to
pretty print the actual JSON response.
#### `nielsen tv apply`
The `tv apply` subcommand can be used to apply specific metadata to a file and
rename it rather than attempting to infer all the metadata from the filename.
For example, you may have a collection of files that are already organized by
series name and season, but the file names are simply: `1.mkv`, `2.mkv`,
`3.mkv`, etc. While you may know exactly what they are, `nielsen` only
considers the filename when attempting to infer metadata (not parent directory
names).
Specifying the series name, season number, and episode number applies the
information to a single file. Specifying only the series name and season number
can apply information about each episode in the season to a collection of
files.
```bash
# Rename a single file
nielsen tv apply --series "Ted Lasso" --season 2 --episode 5 "5.mkv"
# Map each file in a directory to an episode in a season
nielsen tv apply --series "Ted Lasso" --season 2 $(ls | sort -n)
```
It's worth checking on how your shell will expand the `*` before attempting to
use `apply` on all files in a directory, because the files are processed in the
order they're given. Without leading zeroes, they're likely to expand in
lexicographical order rather than numerical order, e.g. `1.mkv`, `10.mkv`,
`11.mkv`, `2.mkv`, `3.mkv`, `4.mkv`, etc. `ls | sort -n` can be used to ensure
the files are sorted numerically.
## Configuration
`nielsen` uses an [INI file][wikipedia-ini] for configuration. The module will
look for files in the following locations, and load them in order (overwriting
old values with newer values as they're loaded):
- `/etc/nielsen/config.ini`
- `~/.config/nielsen/config.ini`
The CLI uses these configuration files to determine its default behavior, but
also accepts a few command line flags (e.g. `--[no-]organize`) to modify its
behavior at runtime. Command line arguments will take precedence over the
configuration files.
### Sections and Options
Each section (denoted with square-brackets around the name) may contain
multiple options.
#### `[nielsen]`
Contains options about the behavior of the application itself.
##### `fetch`
Whether or not to create and use a `Fetcher` to obtain additional metadata
about a file. If there is sufficient information in the filename or there is no
network connection, the data fetching process can be skipped altogether.
*Values*: `True` or `False`
*Default*: `True`
##### `interactive`
Whether or not to prompt the user to select their desired result when a
`Fetcher` yields multiple results (e.g. "The Office"). In non-interactive mode,
the first result is used.
*Values*: `True` or `False`
*Default*: `True`
##### `logfile`
The location on disk to which `nielsen` log output should be written.
*Value*: *A file the user can write to*
*Default*: `~/.local/log/nielsen/nielsen.log`
##### `loglevel`
The [Python logging level][python-logging] at which to filter log messages.
*Values*: `NOTSET`, `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`
*Default*: `WARNING`
##### `mode`
The [numeric notation][wikipedia-fs-mode] for the file mode (or permissions) a
file should be given during processing.
*Default*: 644
##### `organize`
Whether or not to move files to the media library during processing.
*Values*: `True` or `False`
*Default*: `True`
##### `rename`
Whether or not to rename a file with its new metadata during processing.
*Values*: `True` or `False`
*Default*: `True`
##### `simulate`
Whether or not to actually modify files (e.g. rename and move them), or just
print/log the actions which would otherwise be taken during processing.
*Values*: `True` or `False`
*Default*: `False`
##### `transform`
Whether or not to transform (or modify) the inferred or fetched data during
processing. The exact nature of these transformations are defined by the
`MediaType`.
*Values*: `True` or `False`
*Default*: `True`
#### `[media]`
Contains options to apply to generic `Media` objects. Currently, there's no
real use for this. However, options described here can be used in any other
`Media` type section (e.g. `tv`).
##### `library`
The root directory into which a file should be moved as part of its processing.
Each `Media` type may define its own `library` path.
*Value*: *A directory the user can write to*
*Default*: `$HOME`
##### `owner`
The user name or system UID which should own the file after organizing. This
value is optional, and if left undefined, the file ownership will not be
changed when organizing.
*Value*: A system username (e.g. `irish`) or UID (e.g. `1000`).
*Default*: `None`
##### `group`
The group name or system GID which should own the file after organizing. This
value is optional, and if left undefined, the file ownership will not be
changed when organizing.
*Value*: A system group name (e.g. `user`) or GID (e.g. `1001`).
*Default*: `None`
#### `[tv]`
Contains options to apply to `TV` objects. It is recommended that you set a
`library` option to keep each media type separated. This value will overwrite
the default `[nielsen]` or `[media]` section options for files processed as
`TV`.
#### `[tv/transform/series]`
This section defines transformations for `TV.series` values. This can be used
to normalize series names so that all files get organized into the same
directory and are named consistently. Consider the series [Marvel's Agents of
S.H.I.E.L.D.][tvmaze-agents-of-shield]. You may have files with various naming
conventions:
1. Agents Of S.H.I.E.L.D.
1. Agents Of SHIELD
1. Agents Of Shield
1. Agents of S.H.I.E.L.D.
1. Agents of SHIELD
1. Agents of Shield
1. Marvel's Agents Of S.H.I.E.L.D.
1. Marvel's Agents Of SHIELD
1. Marvel's Agents Of Shield
1. Marvel's Agents of S.H.I.E.L.D.
1. Marvel's Agents of SHIELD
1. Marvel's Agents of Shield
By default, `nielsen` will see each of these as a different series. Defining a
variant and a preferred name allows `nielsen` to treat them all as a single
series. The variants used to choose a transformation are case insensitive, so
you can fix capital letters/title casing with minimal repetition.
*Values*: `Variant Series Name = Preferred Series Name`
```ini
[tv/transform/series]
Agents of S.H.I.E.L.D. = Marvel's Agents of S.H.I.E.L.D.
Agents of SHIELD = Marvel's Agents of S.H.I.E.L.D.
Marvel's Agents of S.H.I.E.L.D. = Marvel's Agents of S.H.I.E.L.D.
Marvel's Agents of SHIELD = Marvel's Agents of S.H.I.E.L.D.
Its Always Sunny In Philadelphia = It's Always Sunny in Philadelphia
It's Always Sunny In Philadelphia = It's Always Sunny in Philadelphia
```
#### `[tvmaze/ids]`
Fetching an episode title from [TVMaze][tvmaze] requires a series ID, season
number, and episode number. Once a series name to series ID mapping has been
determined, `nielsen` will attempt to save it in this section to avoid having
to do the same lookup again in the future.
*Values*: `Series Name = Series ID`
[architecture]: ARCHITECTURE.md
[poetry]: https://python-poetry.org/
[pypi-nielsen]: https://pypi.org/project/Nielsen/
[python-logging]: https://docs.python.org/3/library/logging.html#logging-levels
[tvmaze-agents-of-shield]: https://www.tvmaze.com/shows/31/marvels-agents-of-shield
[tvmaze]: https://tvmaze.com/
[wikipedia-fs-mode]: https://en.wikipedia.org/wiki/File-system_permissions#Numeric_notation
[wikipedia-ini]: https://en.wikipedia.org/wiki/INI_file
Raw data
{
"_id": null,
"home_page": "http://irishprime.github.io/Nielsen/",
"name": "nielsen",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.12",
"maintainer_email": null,
"keywords": "metadata, tv, renamer",
"author": "Michael \"Irish\" O'Neill",
"author_email": "irish.dot@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/45/03/5f5b4929a4a550fe5a1fe9a16e1b18b439f062af1b0123cacf8f6e3a1fec/nielsen-3.1.4.tar.gz",
"platform": null,
"description": "# Nielsen\n\nNielsen helps rename and organize digital media collections.\n\nConsider a filename such as `The.Wheel.of.Time.S01E06.720p.WEB.x265-MiNX.mkv`.\nIf you'd prefer something more along the lines of `The Wheel of Time -01.06-\nThe Flame of Tar Valon.mkv`, Nielsen can help.\n\nNielsen endeavors to automatically handle these types of renaming operations,\nas well as move the files into a more hierarchical folder structure that keeps\nyour media directories tidy.\n\n## Requirements\n\n- Python 3.12 (or newer)\n- [Poetry][poetry] (for source installations)\n\n## Install\n\n### PyPI\n\nThis package is published on [PyPI][pypi-nielsen] and can be installed from\nthere with the following command.\n\n```bash\npip install nielsen\n```\n\n### Source\n\nThis package can also be installed from source by cloning this repository and\nusing [Poetry][poetry].\n\n```bash\npoetry install\n```\n\n## Concepts\n\n- [`Media`](./ARCHITECTURE.md#nielsenmediamedia) - Represents a file on disk\n and its metadata. The specific subclass determines how metadata is inferred\n and which `Fetcher` should be used.\n- [`Fetcher`](./ARCHITECTURE.md#nielsenfetcherfetcher) - Queries external\n systems/services for metadata about a given `Media` instance.\n- [`Processor`](./ARCHITECTURE.md#nielsenprocessorprocessor) - A grouping of\n a `MediaType` and `Fetcher`. Given a file, the `Processor` creates the\n appropriate `Media` (based on the `MediaType`) and `Fetcher` to query for\n metadata.\n\nUnder the hood, \"processing\" a file will create a `Media` object from the given\npath and `MediaType`, infer metadata based on the filename (e.g. TV series\nname, season number, episode number, and episode title).\n\nIf the `fetch` option is enabled, then a `Fetcher` will also be created to\nquery more information (e.g. `Ted.Lasso.S01.E01.mp4` doesn't give us an episode\ntitle, but the `Fetcher` can ask [TVMaze][tvmaze] for it).\n\n`nielsen` can then rename the file (e.g. `Ted Lasso -01.04- For the\nChildren.mp4`) and move it to your media library (e.g. `~/Videos/TV/Ted\nLasso/Season 01/`).\n\nSee the [ARCHITECTURE][architecture] file for more detailed information.\n\n## Usage\n\nThe primary use case `nielsen` is intended to handle is that of renaming a file\nand moving it into the correct location on disk. This is done with the\n`process` subcommand.\n\nAll commands (and subcommands) will accept a `--help` flag to provide more\ninformation about usage.\n\n```bash\n# Process a given file\nnielsen process PATH_TO_FILE\n\n# See a list of all subcommands\nnielsen --help\n```\n\n### `tv` subcommand\n\nThe `tv` subcommand can be used to make some simple queries to TVMaze and to\napply the results of those queries to files on-demand.\n\n#### `nielsen tv fetch`\n\nThe `tv fetch` subcommand queries the TVMaze API. The more information you\nprovide, the more specific the results. You can fetch information about a\nseries, a season, or an episode.\n\n```bash\n# Get information about a series\nnielsen tv fetch --series \"Ted Lasso\"\n# Get information about a specific season of a series\nnielsen tv fetch --series \"Ted Lasso\" --season 2\n# Get information about a specific episode of a season of a series\nnielsen tv fetch --series \"Ted Lasso\" --season 2 --episode 5\n```\n\nAdditionally, the `--raw` flag can be used with any of the commands above to\npretty print the actual JSON response.\n\n#### `nielsen tv apply`\n\nThe `tv apply` subcommand can be used to apply specific metadata to a file and\nrename it rather than attempting to infer all the metadata from the filename.\n\nFor example, you may have a collection of files that are already organized by\nseries name and season, but the file names are simply: `1.mkv`, `2.mkv`,\n`3.mkv`, etc. While you may know exactly what they are, `nielsen` only\nconsiders the filename when attempting to infer metadata (not parent directory\nnames).\n\nSpecifying the series name, season number, and episode number applies the\ninformation to a single file. Specifying only the series name and season number\ncan apply information about each episode in the season to a collection of\nfiles.\n\n```bash\n# Rename a single file\nnielsen tv apply --series \"Ted Lasso\" --season 2 --episode 5 \"5.mkv\"\n# Map each file in a directory to an episode in a season\nnielsen tv apply --series \"Ted Lasso\" --season 2 $(ls | sort -n)\n```\n\nIt's worth checking on how your shell will expand the `*` before attempting to\nuse `apply` on all files in a directory, because the files are processed in the\norder they're given. Without leading zeroes, they're likely to expand in\nlexicographical order rather than numerical order, e.g. `1.mkv`, `10.mkv`,\n`11.mkv`, `2.mkv`, `3.mkv`, `4.mkv`, etc. `ls | sort -n` can be used to ensure\nthe files are sorted numerically.\n\n## Configuration\n\n`nielsen` uses an [INI file][wikipedia-ini] for configuration. The module will\nlook for files in the following locations, and load them in order (overwriting\nold values with newer values as they're loaded):\n\n- `/etc/nielsen/config.ini`\n- `~/.config/nielsen/config.ini`\n\nThe CLI uses these configuration files to determine its default behavior, but\nalso accepts a few command line flags (e.g. `--[no-]organize`) to modify its\nbehavior at runtime. Command line arguments will take precedence over the\nconfiguration files.\n\n### Sections and Options\n\nEach section (denoted with square-brackets around the name) may contain\nmultiple options.\n\n#### `[nielsen]`\n\nContains options about the behavior of the application itself.\n\n##### `fetch`\n\nWhether or not to create and use a `Fetcher` to obtain additional metadata\nabout a file. If there is sufficient information in the filename or there is no\nnetwork connection, the data fetching process can be skipped altogether.\n\n*Values*: `True` or `False`\n\n*Default*: `True`\n\n##### `interactive`\n\nWhether or not to prompt the user to select their desired result when a\n`Fetcher` yields multiple results (e.g. \"The Office\"). In non-interactive mode,\nthe first result is used.\n\n*Values*: `True` or `False`\n\n*Default*: `True`\n\n##### `logfile`\n\nThe location on disk to which `nielsen` log output should be written.\n\n*Value*: *A file the user can write to*\n\n*Default*: `~/.local/log/nielsen/nielsen.log`\n\n##### `loglevel`\n\nThe [Python logging level][python-logging] at which to filter log messages.\n\n*Values*: `NOTSET`, `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`\n\n*Default*: `WARNING`\n\n##### `mode`\n\nThe [numeric notation][wikipedia-fs-mode] for the file mode (or permissions) a\nfile should be given during processing.\n\n*Default*: 644\n\n##### `organize`\n\nWhether or not to move files to the media library during processing.\n\n*Values*: `True` or `False`\n\n*Default*: `True`\n\n##### `rename`\n\nWhether or not to rename a file with its new metadata during processing.\n\n*Values*: `True` or `False`\n\n*Default*: `True`\n\n##### `simulate`\n\nWhether or not to actually modify files (e.g. rename and move them), or just\nprint/log the actions which would otherwise be taken during processing.\n\n*Values*: `True` or `False`\n\n*Default*: `False`\n\n##### `transform`\n\nWhether or not to transform (or modify) the inferred or fetched data during\nprocessing. The exact nature of these transformations are defined by the\n`MediaType`.\n\n*Values*: `True` or `False`\n\n*Default*: `True`\n\n#### `[media]`\n\nContains options to apply to generic `Media` objects. Currently, there's no\nreal use for this. However, options described here can be used in any other\n`Media` type section (e.g. `tv`).\n\n##### `library`\n\nThe root directory into which a file should be moved as part of its processing.\nEach `Media` type may define its own `library` path.\n\n*Value*: *A directory the user can write to*\n\n*Default*: `$HOME`\n\n##### `owner`\n\nThe user name or system UID which should own the file after organizing. This\nvalue is optional, and if left undefined, the file ownership will not be\nchanged when organizing.\n\n*Value*: A system username (e.g. `irish`) or UID (e.g. `1000`).\n\n*Default*: `None`\n\n##### `group`\n\nThe group name or system GID which should own the file after organizing. This\nvalue is optional, and if left undefined, the file ownership will not be\nchanged when organizing.\n\n*Value*: A system group name (e.g. `user`) or GID (e.g. `1001`).\n\n*Default*: `None`\n\n#### `[tv]`\n\nContains options to apply to `TV` objects. It is recommended that you set a\n`library` option to keep each media type separated. This value will overwrite\nthe default `[nielsen]` or `[media]` section options for files processed as\n`TV`.\n\n#### `[tv/transform/series]`\n\nThis section defines transformations for `TV.series` values. This can be used\nto normalize series names so that all files get organized into the same\ndirectory and are named consistently. Consider the series [Marvel's Agents of\nS.H.I.E.L.D.][tvmaze-agents-of-shield]. You may have files with various naming\nconventions:\n\n1. Agents Of S.H.I.E.L.D.\n1. Agents Of SHIELD\n1. Agents Of Shield\n1. Agents of S.H.I.E.L.D.\n1. Agents of SHIELD\n1. Agents of Shield\n1. Marvel's Agents Of S.H.I.E.L.D.\n1. Marvel's Agents Of SHIELD\n1. Marvel's Agents Of Shield\n1. Marvel's Agents of S.H.I.E.L.D.\n1. Marvel's Agents of SHIELD\n1. Marvel's Agents of Shield\n\nBy default, `nielsen` will see each of these as a different series. Defining a\nvariant and a preferred name allows `nielsen` to treat them all as a single\nseries. The variants used to choose a transformation are case insensitive, so\nyou can fix capital letters/title casing with minimal repetition.\n\n*Values*: `Variant Series Name = Preferred Series Name`\n\n```ini\n[tv/transform/series]\nAgents of S.H.I.E.L.D. = Marvel's Agents of S.H.I.E.L.D.\nAgents of SHIELD = Marvel's Agents of S.H.I.E.L.D.\nMarvel's Agents of S.H.I.E.L.D. = Marvel's Agents of S.H.I.E.L.D.\nMarvel's Agents of SHIELD = Marvel's Agents of S.H.I.E.L.D.\n\nIts Always Sunny In Philadelphia = It's Always Sunny in Philadelphia\nIt's Always Sunny In Philadelphia = It's Always Sunny in Philadelphia\n```\n\n#### `[tvmaze/ids]`\n\nFetching an episode title from [TVMaze][tvmaze] requires a series ID, season\nnumber, and episode number. Once a series name to series ID mapping has been\ndetermined, `nielsen` will attempt to save it in this section to avoid having\nto do the same lookup again in the future.\n\n*Values*: `Series Name = Series ID`\n\n[architecture]: ARCHITECTURE.md\n[poetry]: https://python-poetry.org/\n[pypi-nielsen]: https://pypi.org/project/Nielsen/\n[python-logging]: https://docs.python.org/3/library/logging.html#logging-levels\n[tvmaze-agents-of-shield]: https://www.tvmaze.com/shows/31/marvels-agents-of-shield\n[tvmaze]: https://tvmaze.com/\n[wikipedia-fs-mode]: https://en.wikipedia.org/wiki/File-system_permissions#Numeric_notation\n[wikipedia-ini]: https://en.wikipedia.org/wiki/INI_file\n",
"bugtrack_url": null,
"license": "GPL-3.0-or-later",
"summary": "Organize your digital media collections.",
"version": "3.1.4",
"project_urls": {
"Documentation": "https://github.com/IrishPrime/Nielsen/wiki",
"Homepage": "http://irishprime.github.io/Nielsen/",
"Repository": "https://github.com/IrishPrime/Nielsen/"
},
"split_keywords": [
"metadata",
" tv",
" renamer"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "5c4bed4d663ddc7a7a19afba27a272d67e724528699909307d2d3c13532a5cb7",
"md5": "a2b5a8ad09c89ab55a80ab6c267d158f",
"sha256": "1097eb553364d99f48645d07a9d56f3d5c7b1010532362f8b8cca4bfe8963802"
},
"downloads": -1,
"filename": "nielsen-3.1.4-py3-none-any.whl",
"has_sig": false,
"md5_digest": "a2b5a8ad09c89ab55a80ab6c267d158f",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.12",
"size": 33639,
"upload_time": "2024-11-17T17:20:14",
"upload_time_iso_8601": "2024-11-17T17:20:14.619244Z",
"url": "https://files.pythonhosted.org/packages/5c/4b/ed4d663ddc7a7a19afba27a272d67e724528699909307d2d3c13532a5cb7/nielsen-3.1.4-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "45035f5b4929a4a550fe5a1fe9a16e1b18b439f062af1b0123cacf8f6e3a1fec",
"md5": "452e4461739e768e37da8df5916653a4",
"sha256": "d582daef5ee69a2dbb984b9469e2941a1c0e648b1d6bf770afe168f7fb6fc2a8"
},
"downloads": -1,
"filename": "nielsen-3.1.4.tar.gz",
"has_sig": false,
"md5_digest": "452e4461739e768e37da8df5916653a4",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.12",
"size": 33032,
"upload_time": "2024-11-17T17:20:16",
"upload_time_iso_8601": "2024-11-17T17:20:16.391987Z",
"url": "https://files.pythonhosted.org/packages/45/03/5f5b4929a4a550fe5a1fe9a16e1b18b439f062af1b0123cacf8f6e3a1fec/nielsen-3.1.4.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-11-17 17:20:16",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "IrishPrime",
"github_project": "Nielsen",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "nielsen"
}