[![Stand With Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/banner2-direct.svg)](https://vshymanskyy.github.io/StandWithUkraine)
---
[![image](http://img.shields.io/pypi/v/beetcamp.svg)](https://pypi.python.org/pypi/beetcamp)
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=snejus_beetcamp&metric=alert_status)](https://sonarcloud.io/dashboard?id=snejus_beetcamp)
[![Coverage Status](https://coveralls.io/repos/github/snejus/beetcamp/badge.svg?branch=main)](https://coveralls.io/github/snejus/beetcamp?branch=main)
[ ![Hits](https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fgithub.com%2Fsnejus%2Fbeetcamp&count_bg=%23842424&title_bg=%23846060&icon=postwoman.svg&icon_color=%23CF4D4D&title=hits&edge_flat=true)](https://hits.seeyoufarm.com)
Bandcamp autotagger plugin for [beets]. It mostly focuses on
- Staying up-to-date with information Bandcamp provide in the JSON metadata
- Parsing **all possible** (if relevant) metadata from various places
- For example, a catalog number given in the release or media description
- Correctness of the data
- For example, determining artist names from various artists releases
- Compliance with MusicBrainz fields format, to remove the need for pre-processing if, for
example, one wishes to upload the metadata to MB.
Thanks to [unrblt] for [beets-bandcamp] providing the idea and initial implementation.
[beets]: https://github.com/beetbox/beets
[unrblt]: https://github.com/unrblt
[beets-bandcamp]: https://github.com/unrblt/beets-bandcamp
# Installation
## Recommended method
1. Install `beets` with `pipx` so that it's isolated from your system and other projects
```bash
pipx install beets
```
2. Inject `beetcamp` and other dependencies that you need. The `--include-apps` flag is required to make sure that `beetcamp` is made available in your command line.
```bash
pipx inject --include-apps beets beetcamp [python-mpd2 ...]
```
3. Add `bandcamp` to the `plugins` list to your beets configuration file.
## Otherwise
Navigate to your `beets` virtual environment and install the plug-in with
```bash
pip install beetcamp
```
# CLI
The plugin exposes some of its functionality through a command-line application `beetcamp`:
```xml
usage: beetcamp [-h] [-a] [-l] [-t] [-o INDEX] [-p PAGE] (release_url | query)
Get bandcamp release metadata from the given <release-url> or perform
bandcamp search with <query>. Anything that does not start with https://
will be assumed to be a query. Search type flags: -a for albums, -l for
labels and artists, -t for tracks. By default, all types are searched.
positional arguments:
release_url Release URL, starting with https:// OR
query Search query
optional arguments:
-h, --help show this help message and exit
-a, --album Search albums
-l, --label Search labels and artists
-t, --track Search tracks
-o INDEX, --open INDEX
Open search result indexed by INDEX in the browser
-p PAGE, --page PAGE The results page to show, 1 by default
```
- Use `beetcamp <bandcamp-release-url>` to return release metadata in JSON format.
- Use `beetcamp [-alt] <query>` to search albums, labels and tracks on Bandcamp and return
results in JSON.
- Search results are indexed - add `-o <index>` in order to open the chosen URL in the browser.
You can see how the data looks below (the output is prettified with [rich-tables]).
![image](https://github.com/snejus/beetcamp/blob/fe6ea71a0ab0035d657d13f664de957befb4552c/images/search.png?raw=true)
[rich-tables]: https://github.com/snejus/rich-tables
# Configuration
## Default
```yaml
bandcamp:
include_digital_only_tracks: true
search_max: 2
art: yes
comments_separator: "\n---\n"
truncate_comments: no
exclude_extra_fields: []
genre:
capitalize: no
maximum: 0
always_include: []
mode: progressive # classical, progressive or psychedelic
```
---
#### `include_digital_only_tracks`
- Type: **bool**
- Default: `true`
For media that isn't `Digital Media`, include all tracks, even if their titles contain
**digital only** (or alike).
If you have `False` here, then, for example, a `Vinyl` media of an album will only include
the tracks that are supposed to be found in that media.
---
#### `search_max`
- Type: **int**
- Default: `2`.
Number of items to fetch through search, maximum is 18. Usually, a matching release should
be found among the first two items.
---
#### `art`
- Type: **bool**
- Default: `false`.
Add a source to the
[FetchArt](http://beets.readthedocs.org/en/latest/plugins/fetchart.html) plug-in to
download album art for Bandcamp albums (requires `FetchArt` plug-in enabled).
---
#### `comments_separator`
- Type: **string**
- Default: `"\n---\n"`.
The separator that divides release, media descriptions and credits within the `comments`
field. By default you would get
Description
---
Media description
---
Credits
---
### `truncate_comments`
- Type: **bool**
- Default: `false`.
MPD users may have experienced issues with songs that have very long comments: if there is
a track in the queue with a comments field longer than 4047 characters, MPD fails to
return any metadata.
This configuration option truncates the `comments` field to the maximum length that MPD
can handle, and saves the full comment as a flexible attribute on the album.
---
#### `exclude_extra_fields`
- Type: **list**
- Default: _`empty`_
List of fields that you _do not_ want to see in the metadata. For example, if you find the
inclusion of `comments` irrelevant and are not interested in lyrics, you could specify
```yaml
bandcamp:
search_max: 5
exclude_extra_fields:
- lyrics
- comments
```
and the plugin will skip them.
You cannot exclude `album`, `album_id`, `artist_id`, `media` and `data_url` album fields.
---
#### `genre`
- Type: **object**
- Default:
```yaml
genre:
capitalize: no
maximum: 0 # no maximum
mode: progressive
always_include: []
```
**genre.capitalize**: **Classical, Techno** instead of default **classical, techno**.
For consistency, this option also applies to the `style` field.
**genre.maximum** caps the maximum number of included genres. This may be of
value in those cases where artists/labels begin the list with the most relevant keywords,
however be aware it is rarely the case.
**genre.mode** accepts one of the following options: **classical** (less genres) or **progressive** or
**psychedelic** (more genres). Each later one is more flexible regarding what is a valid
genre and what is not. See below (we use the list of [musicbrainz genres] for reference).
**genre.always_include**: genre patterns that override the mode and always match
successfully. For example, if you want to bypass checks for every keyword that ends with
`core`, you could specify
```yaml
genre:
always_include:
- "core$"
```
##### `genre` modes
We can place all keywords into the following buckets:
| type | | |
| :---: | ------------------------------------ | -------------------------------------------------------------------- |
| **1** | **`genre`** | a valid single-word musicbrainz genre |
| **1** | **`more specific genre`** | a valid musicbrainz genre made of multiple words |
| **2** | **`somegenre`** **`someothergenre`** | each of the words is a valid musicbrainz genre, but the combo is not |
| **3** | very specific **`genre`** | not all words are valid genres, but the very last one is |
| **4** | maybe **`genre`** but | but it is followed by noise at the end |
| **4** | some sort of location | irrelevant |
- **classical** mode strictly follows the musicbrainz list of genres, therefore it covers
**type 1** only
- **progressive** mode, in addition to the above, takes into account each of the words that
make up the keyword and will be fine as long as each of those words maps to some sort of
genre from the musicbrainz list. It covers **types 1 and 2**.
- **psychedelic** (or **noise**) mode, in addition to the above, treats the keyword as a
valid genre as long as **the last word** in it maps to some genre - covering **types 1 to 3**.
This one should include the hottest genre naming trends but is also liable to covering the
latest `<some-label>-<genre>` or `<some-city>-<some-very-generic-genre>` trends which may
not be ideal. It should though be the best option for those who enjoy detailed, fine-grained
stats.
- **type 4** is ignored in each case (can be overridden and included through the `genre.include` option).
See below for some examples and a comparison between the modes.
| type | keyword | classical | progressive | psychedelic |
| ----: | ----------------------- | :-------: | :---------: | :---------: |
| **1** | **`techno`** | ✔ | ✔ | ✔ |
| **1** | **`funk`** | ✔ | ✔ | ✔ |
| **1** | **`ambient`** | ✔ | ✔ | ✔ |
| **1** | **`noise`** | ✔ | ✔ | ✔ |
| **1** | **`ambient techno`** | ✔ | ✔ | ✔ |
| **2** | **`techno`** **`funk`** | ✖ | ✔ | ✔ |
| **4** | funky | ✖ | ✖ | ✖ |
| **4** | bleep | ✖ | ✖ | ✖ |
| **3** | funky **`techno`** | ✖ | ✖ | ✔ |
| **4** | bleepy beep | ✖ | ✖ | ✖ |
| **3** | bleepy beep **`noise`** | ✖ | ✖ | ✔ |
| **4** | bleepy **`noise`** beep | ✖ | ✖ | ✖ |
# Usage
This plug-in uses Bandcamp release URL as `album_id` (`.../album/...` for albums and
`.../track/...` for singletons). If no matching release is found during the import you can
select `enter Id` and paste the URL that you have.
## Supported metadata
| field | singleton | album track | album | note |
| -------------: | :-------: | :---------: | :---: | :---------------------------------------------------------------------------------: |
| `album` | | | ✔ | |
| `album_id` | | | ✔ | release Bandcamp URL |
| `albumartist` | | | ✔ | |
| `albumstatus` | | | ✔ | |
| `albumtype` | \*✔ | | ✔ | |
| `albumtypes` | \*✔ | | \*✔ | |
| `artist` | ✔ | ✔ | ✔ | |
| `artist_id` | ✔ | | ✔ | label / publisher Bandcamp URL |
| `catalognum` | \*✔ | | ✔ | |
| `comments` | \*✔ | | \*✔ | release and media descriptions, and credits |
| `country` | \*✔ | | ✔ | |
| `day` | \*✔ | | ✔ | |
| `disctitle` | \*✔ | ✔ | | |
| `genre` | \*✔ | | \*✔ | comma-delimited list of **release keywords** which match [musicbrainz genres] |
| `index` | | ✔ | | |
| `label` | \*✔ | | ✔ | |
| `length` | ✔ | ✔ | | |
| `lyrics` | \*✔ | \*✔ | | |
| `media` | \*✔ | ✔ | ✔ | |
| `medium` | | ✔ | | likely to be inaccurate, since it depends on information in the release description |
| `mediums` | | | ✔ | |
| `medium_index` | | ✔ | | for now, same as `index` |
| `medium_total` | | ✔ | | total number of tracks in the release |
| `month` | \*✔ | | ✔ | |
| `style` | \*✔ | | \*✔ | Bandcamp genre tag |
| `title` | ✔ | ✔ | | |
| `track_alt` | ✔ | ✔ | | |
| `track_id` | | ✔ | | track URL |
| `va` | | | ✔ | |
| `year` | \*✔ | | ✔ | |
**\*** Available with `beets` versions `1.5` or higher.
[musicbrainz genres]: https://beta.musicbrainz.org/genres
Raw data
{
"_id": null,
"home_page": "https://github.com/snejus/beetcamp",
"name": "beetcamp",
"maintainer": null,
"docs_url": null,
"requires_python": "<4,>=3.9",
"maintainer_email": null,
"keywords": "music, bandcamp, beets, metadata",
"author": "\u0160ar\u016bnas Nejus",
"author_email": "snejus@pm.me",
"download_url": "https://files.pythonhosted.org/packages/56/af/0caa6fbc2ea2155e0a833d306880705a19ee01241b2c62ac05ac83f4fe3d/beetcamp-0.21.0.tar.gz",
"platform": null,
"description": "[![Stand With Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/banner2-direct.svg)](https://vshymanskyy.github.io/StandWithUkraine)\n\n---\n\n[![image](http://img.shields.io/pypi/v/beetcamp.svg)](https://pypi.python.org/pypi/beetcamp)\n[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=snejus_beetcamp&metric=alert_status)](https://sonarcloud.io/dashboard?id=snejus_beetcamp)\n[![Coverage Status](https://coveralls.io/repos/github/snejus/beetcamp/badge.svg?branch=main)](https://coveralls.io/github/snejus/beetcamp?branch=main)\n[ ![Hits](https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fgithub.com%2Fsnejus%2Fbeetcamp&count_bg=%23842424&title_bg=%23846060&icon=postwoman.svg&icon_color=%23CF4D4D&title=hits&edge_flat=true)](https://hits.seeyoufarm.com)\n\nBandcamp autotagger plugin for [beets]. It mostly focuses on\n\n- Staying up-to-date with information Bandcamp provide in the JSON metadata\n- Parsing **all possible** (if relevant) metadata from various places\n - For example, a catalog number given in the release or media description\n- Correctness of the data\n - For example, determining artist names from various artists releases\n- Compliance with MusicBrainz fields format, to remove the need for pre-processing if, for\n example, one wishes to upload the metadata to MB.\n\nThanks to [unrblt] for [beets-bandcamp] providing the idea and initial implementation.\n\n[beets]: https://github.com/beetbox/beets\n[unrblt]: https://github.com/unrblt\n[beets-bandcamp]: https://github.com/unrblt/beets-bandcamp\n\n# Installation\n\n## Recommended method\n\n1. Install `beets` with `pipx` so that it's isolated from your system and other projects\n\n```bash\npipx install beets\n```\n\n2. Inject `beetcamp` and other dependencies that you need. The `--include-apps` flag is required to make sure that `beetcamp` is made available in your command line.\n\n```bash\npipx inject --include-apps beets beetcamp [python-mpd2 ...]\n```\n\n3. Add `bandcamp` to the `plugins` list to your beets configuration file.\n\n## Otherwise\n\nNavigate to your `beets` virtual environment and install the plug-in with\n\n```bash\npip install beetcamp\n```\n\n# CLI\n\nThe plugin exposes some of its functionality through a command-line application `beetcamp`:\n\n```xml\nusage: beetcamp [-h] [-a] [-l] [-t] [-o INDEX] [-p PAGE] (release_url | query)\n\nGet bandcamp release metadata from the given <release-url> or perform\nbandcamp search with <query>. Anything that does not start with https://\nwill be assumed to be a query. Search type flags: -a for albums, -l for\nlabels and artists, -t for tracks. By default, all types are searched.\n\npositional arguments:\n release_url Release URL, starting with https:// OR\n query Search query\n\noptional arguments:\n -h, --help show this help message and exit\n -a, --album Search albums\n -l, --label Search labels and artists\n -t, --track Search tracks\n -o INDEX, --open INDEX\n Open search result indexed by INDEX in the browser\n -p PAGE, --page PAGE The results page to show, 1 by default\n```\n\n- Use `beetcamp <bandcamp-release-url>` to return release metadata in JSON format.\n- Use `beetcamp [-alt] <query>` to search albums, labels and tracks on Bandcamp and return\n results in JSON.\n- Search results are indexed - add `-o <index>` in order to open the chosen URL in the browser.\n\nYou can see how the data looks below (the output is prettified with [rich-tables]).\n\n![image](https://github.com/snejus/beetcamp/blob/fe6ea71a0ab0035d657d13f664de957befb4552c/images/search.png?raw=true)\n\n[rich-tables]: https://github.com/snejus/rich-tables\n\n# Configuration\n\n## Default\n\n```yaml\nbandcamp:\n include_digital_only_tracks: true\n search_max: 2\n art: yes\n comments_separator: \"\\n---\\n\"\n truncate_comments: no\n exclude_extra_fields: []\n genre:\n capitalize: no\n maximum: 0\n always_include: []\n mode: progressive # classical, progressive or psychedelic\n```\n\n---\n\n#### `include_digital_only_tracks`\n\n- Type: **bool**\n- Default: `true`\n\nFor media that isn't `Digital Media`, include all tracks, even if their titles contain\n**digital only** (or alike).\n\nIf you have `False` here, then, for example, a `Vinyl` media of an album will only include\nthe tracks that are supposed to be found in that media.\n\n---\n\n#### `search_max`\n\n- Type: **int**\n- Default: `2`.\n\nNumber of items to fetch through search, maximum is 18. Usually, a matching release should\nbe found among the first two items.\n\n---\n\n#### `art`\n\n- Type: **bool**\n- Default: `false`.\n\nAdd a source to the\n[FetchArt](http://beets.readthedocs.org/en/latest/plugins/fetchart.html) plug-in to\ndownload album art for Bandcamp albums (requires `FetchArt` plug-in enabled).\n\n---\n\n#### `comments_separator`\n\n- Type: **string**\n- Default: `\"\\n---\\n\"`.\n\nThe separator that divides release, media descriptions and credits within the `comments`\nfield. By default you would get\n\n Description\n ---\n Media description\n ---\n Credits\n\n---\n\n### `truncate_comments`\n\n- Type: **bool**\n- Default: `false`.\n\nMPD users may have experienced issues with songs that have very long comments: if there is\na track in the queue with a comments field longer than 4047 characters, MPD fails to\nreturn any metadata.\n\nThis configuration option truncates the `comments` field to the maximum length that MPD\ncan handle, and saves the full comment as a flexible attribute on the album.\n\n---\n\n#### `exclude_extra_fields`\n\n- Type: **list**\n- Default: _`empty`_\n\nList of fields that you _do not_ want to see in the metadata. For example, if you find the\ninclusion of `comments` irrelevant and are not interested in lyrics, you could specify\n\n```yaml\nbandcamp:\n search_max: 5\n exclude_extra_fields:\n - lyrics\n - comments\n```\n\nand the plugin will skip them.\n\nYou cannot exclude `album`, `album_id`, `artist_id`, `media` and `data_url` album fields.\n\n---\n\n#### `genre`\n\n- Type: **object**\n- Default:\n ```yaml\n genre:\n capitalize: no\n maximum: 0 # no maximum\n mode: progressive\n always_include: []\n ```\n\n**genre.capitalize**: **Classical, Techno** instead of default **classical, techno**.\nFor consistency, this option also applies to the `style` field.\n\n**genre.maximum** caps the maximum number of included genres. This may be of\nvalue in those cases where artists/labels begin the list with the most relevant keywords,\nhowever be aware it is rarely the case.\n\n**genre.mode** accepts one of the following options: **classical** (less genres) or **progressive** or\n**psychedelic** (more genres). Each later one is more flexible regarding what is a valid\ngenre and what is not. See below (we use the list of [musicbrainz genres] for reference).\n\n**genre.always_include**: genre patterns that override the mode and always match\nsuccessfully. For example, if you want to bypass checks for every keyword that ends with\n`core`, you could specify\n\n```yaml\ngenre:\n always_include:\n - \"core$\"\n```\n\n##### `genre` modes\n\nWe can place all keywords into the following buckets:\n\n| type | | |\n| :---: | ------------------------------------ | -------------------------------------------------------------------- |\n| **1** | **`genre`** | a valid single-word musicbrainz genre |\n| **1** | **`more specific genre`** | a valid musicbrainz genre made of multiple words |\n| **2** | **`somegenre`** **`someothergenre`** | each of the words is a valid musicbrainz genre, but the combo is not |\n| **3** | very specific **`genre`** | not all words are valid genres, but the very last one is |\n| **4** | maybe **`genre`** but | but it is followed by noise at the end |\n| **4** | some sort of location | irrelevant |\n\n- **classical** mode strictly follows the musicbrainz list of genres, therefore it covers\n **type 1** only\n- **progressive** mode, in addition to the above, takes into account each of the words that\n make up the keyword and will be fine as long as each of those words maps to some sort of\n genre from the musicbrainz list. It covers **types 1 and 2**.\n- **psychedelic** (or **noise**) mode, in addition to the above, treats the keyword as a\n valid genre as long as **the last word** in it maps to some genre - covering **types 1 to 3**.\n This one should include the hottest genre naming trends but is also liable to covering the\n latest `<some-label>-<genre>` or `<some-city>-<some-very-generic-genre>` trends which may\n not be ideal. It should though be the best option for those who enjoy detailed, fine-grained\n stats.\n- **type 4** is ignored in each case (can be overridden and included through the `genre.include` option).\n\nSee below for some examples and a comparison between the modes.\n\n| type | keyword | classical | progressive | psychedelic |\n| ----: | ----------------------- | :-------: | :---------: | :---------: |\n| **1** | **`techno`** | \u2714 | \u2714 | \u2714 |\n| **1** | **`funk`** | \u2714 | \u2714 | \u2714 |\n| **1** | **`ambient`** | \u2714 | \u2714 | \u2714 |\n| **1** | **`noise`** | \u2714 | \u2714 | \u2714 |\n| **1** | **`ambient techno`** | \u2714 | \u2714 | \u2714 |\n| **2** | **`techno`** **`funk`** | \u2716 | \u2714 | \u2714 |\n| **4** | funky | \u2716 | \u2716 | \u2716 |\n| **4** | bleep | \u2716 | \u2716 | \u2716 |\n| **3** | funky **`techno`** | \u2716 | \u2716 | \u2714 |\n| **4** | bleepy beep | \u2716 | \u2716 | \u2716 |\n| **3** | bleepy beep **`noise`** | \u2716 | \u2716 | \u2714 |\n| **4** | bleepy **`noise`** beep | \u2716 | \u2716 | \u2716 |\n\n# Usage\n\nThis plug-in uses Bandcamp release URL as `album_id` (`.../album/...` for albums and\n`.../track/...` for singletons). If no matching release is found during the import you can\nselect `enter Id` and paste the URL that you have.\n\n## Supported metadata\n\n| field | singleton | album track | album | note |\n| -------------: | :-------: | :---------: | :---: | :---------------------------------------------------------------------------------: |\n| `album` | | | \u2714 | |\n| `album_id` | | | \u2714 | release Bandcamp URL |\n| `albumartist` | | | \u2714 | |\n| `albumstatus` | | | \u2714 | |\n| `albumtype` | \\*\u2714 | | \u2714 | |\n| `albumtypes` | \\*\u2714 | | \\*\u2714 | |\n| `artist` | \u2714 | \u2714 | \u2714 | |\n| `artist_id` | \u2714 | | \u2714 | label / publisher Bandcamp URL |\n| `catalognum` | \\*\u2714 | | \u2714 | |\n| `comments` | \\*\u2714 | | \\*\u2714 | release and media descriptions, and credits |\n| `country` | \\*\u2714 | | \u2714 | |\n| `day` | \\*\u2714 | | \u2714 | |\n| `disctitle` | \\*\u2714 | \u2714 | | |\n| `genre` | \\*\u2714 | | \\*\u2714 | comma-delimited list of **release keywords** which match [musicbrainz genres] |\n| `index` | | \u2714 | | |\n| `label` | \\*\u2714 | | \u2714 | |\n| `length` | \u2714 | \u2714 | | |\n| `lyrics` | \\*\u2714 | \\*\u2714 | | |\n| `media` | \\*\u2714 | \u2714 | \u2714 | |\n| `medium` | | \u2714 | | likely to be inaccurate, since it depends on information in the release description |\n| `mediums` | | | \u2714 | |\n| `medium_index` | | \u2714 | | for now, same as `index` |\n| `medium_total` | | \u2714 | | total number of tracks in the release |\n| `month` | \\*\u2714 | | \u2714 | |\n| `style` | \\*\u2714 | | \\*\u2714 | Bandcamp genre tag |\n| `title` | \u2714 | \u2714 | | |\n| `track_alt` | \u2714 | \u2714 | | |\n| `track_id` | | \u2714 | | track URL |\n| `va` | | | \u2714 | |\n| `year` | \\*\u2714 | | \u2714 | |\n\n**\\*** Available with `beets` versions `1.5` or higher.\n\n[musicbrainz genres]: https://beta.musicbrainz.org/genres\n",
"bugtrack_url": null,
"license": "GPL-2.0",
"summary": "Bandcamp autotagger source for beets (http://beets.io).",
"version": "0.21.0",
"project_urls": {
"Bug Tracker": "https://github.com/snejus/beetcamp/issues",
"Changelog": "https://github.com/snejus/beetcamp/blob/master/CHANGELOG.md",
"Homepage": "https://github.com/snejus/beetcamp",
"Repository": "https://github.com/snejus/beetcamp"
},
"split_keywords": [
"music",
" bandcamp",
" beets",
" metadata"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "6cd394cad1ba1e65a9445655968a6dcdd528cb1352e2389f0921a9f8c0ccd4a0",
"md5": "6fa8a268a4c591089b2f405c4a564830",
"sha256": "e273300377237ad98560aabf5d8e948c492df44f36a852674edd893759c5bd22"
},
"downloads": -1,
"filename": "beetcamp-0.21.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "6fa8a268a4c591089b2f405c4a564830",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4,>=3.9",
"size": 63792,
"upload_time": "2024-12-14T07:21:59",
"upload_time_iso_8601": "2024-12-14T07:21:59.929244Z",
"url": "https://files.pythonhosted.org/packages/6c/d3/94cad1ba1e65a9445655968a6dcdd528cb1352e2389f0921a9f8c0ccd4a0/beetcamp-0.21.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "56af0caa6fbc2ea2155e0a833d306880705a19ee01241b2c62ac05ac83f4fe3d",
"md5": "01470612c3e746fbb10e49c8faec91f2",
"sha256": "1d948e2c83eb78f7d9c8d1a76756fbdbee3aa6416ff8af25a2e100817caa1192"
},
"downloads": -1,
"filename": "beetcamp-0.21.0.tar.gz",
"has_sig": false,
"md5_digest": "01470612c3e746fbb10e49c8faec91f2",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4,>=3.9",
"size": 50431,
"upload_time": "2024-12-14T07:22:02",
"upload_time_iso_8601": "2024-12-14T07:22:02.598439Z",
"url": "https://files.pythonhosted.org/packages/56/af/0caa6fbc2ea2155e0a833d306880705a19ee01241b2c62ac05ac83f4fe3d/beetcamp-0.21.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-12-14 07:22:02",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "snejus",
"github_project": "beetcamp",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "beetcamp"
}