Code Monkey home page Code Monkey logo

party's Introduction

Python Party Downloader (kemono/coomer)

Just something I threw together for fun

Table of Contents
  1. About The Project
  2. Getting Started
  3. Usage
  4. Roadmap

About The Project

Simply put, I got bored one night and threw this project together to pass the time.

(back to top)

Getting Started

I'm not sure if something like this would be welcome on pypi, so I'm just hosting it here on github for now. Quick install instructions

Prerequisites

Just have a modern version of python. ^3.9 should be fine. If you want support for 3.7 or 3.8 just open an issue. I just need to change some typing items and imports for those to work.

  • Ubuntu 22.04

    apt-get install python3 python3-pip
  • Arch/Manjaro (I'm more of an Arch guy)

    sudo pacman -S python python-pip

Installation

You can either clone the repo or install from Releases.

Installation from Releases

  1. Just do it, I guess. \shrugs (This is the latest link as of this post, check releases)
    pip install https://github.com/darkdragn/party/releases/download/v0.7.4/party-0.7.4-py3-none-any.whl

Installation from source

  1. Clone the repo
    git clone https://github.com/darkdragn/party.git
  2. CD into the source dir
    cd party
  3. Install
    pip install .

(back to top)

Usage

Party has 4 basic commands

party <command>

 kemono: Download from kemono
 coomer: Download from coomer
 update: Checks for and downloads new posts
 search: Find creators based on username or id

Download

Kemono and Coomer

A basic breakdown of the options

Usage: party kemono [OPTIONS] SERVICE USER_ID
    Quick download command for kemono.party
  Arguments:
    SERVICE  Specify the service to pull from; Ex(patreon,fanbox,onlyfans)
             [required]
    USER_ID  User id from the url or name from search  [required]
  Options:
    --site TEXT                     [default: https://kemono.party]
    --files / --no-files            [default: files]
    --exclude-external / --no-exclude-external
                                    [default: exclude-external]
    -l, --limit INTEGER             Number of posts to parse. Starts from newest
                                    to oldest.
    --post-id / --no-post-id        Sets file_format to
                                    {ref.post_id}_{ref.filename}, mutually
                                    exclusive with post_title, ordered short and
                                    file_format
    -e, --exclude-extension TEXT    File extension to exclude
    -w, --workers INTEGER           Number of open download connections
                                    [default: 4]
    --name TEXT                     If you provided an id in the argument, you
                                    can provide a name here to skip user db
                                    pull/search.
    -d, --directory TEXT            Specify an output directory
    --post-title / --no-post-title  Sets file_format to
                                    {ref.post_title}_{ref.filename}, mutually
                                    exclusive with post_id, ordered_short and
                                    file_format  [default: no-post-title]
    --ordered-short / --no-ordered-short
                                    Sets file_format to {ref.post_id}_{ref.index
                                    :03}.{ref.extension}, mutually exclusive
                                    with post_id, post_title and file_format
                                    [default: no-ordered-short]
    --file-format TEXT              Used to set the output file format. Mutually
                                    exclusive with post_id, post_title and
                                    ordered short. For custom options, see
                                    post.py for schema fields. For example,
                                    {ref.post_id}_{ref.index:03}_{ref.filename}
                                    would accomplish combining post_id and
                                    ordering the files based on appearance in
                                    the post while keeping the original filename
                                    and extension  [default: {ref.filename}]
    --help                          Show this message and exit.

Examples

  • Download something from kemono

    party kemono patreon diives
  • Download something from coomer

    party coomer onlyfans belledelphine
  • Download from coomer, exclude pictures, and limit to 2 downloads

    party coomer fansly forgottenlovechild -e jpg -e jpeg -e png -w 2

Party will check for existing files while downloading, so incomplete archives can be completed with kemono/coomer or with update.

Update

  • Update an existing directory
    party update diives
    • This will skip creator list download, since we have that data.
    • If the creator was initially downloaded with extensions excluded (option -e), update will retain those exclusions.

Search

Search supports all options kemono and coomer take, e.g. -e, -w, -d, -l

  • Search for a user

    party search belk
  • Search for a user and select results interactively

    party search belk -i
    +-------+------------------+--------------------+---------+
    | Index |       Name       |         ID         | Service |
    +-------+------------------+--------------------+---------+
    |   0   |  Belkos Fanbox   | 877689163103764480 | discord |
    |   1   |     belkadog     |      7025886       | patreon |
    |   2   | Belksasar3DPrint |      37766530      | patreon |
    |   3   |      Belko       |      39123643      |  fanbox |
    +-------+------------------+--------------------+---------+
     Index selection: : 3
     Downloading Belko using default options...
     Downloading from user: Belko
     0%|          | 1/909 [00:00<11:57
  • A more specific search

    party search --site coomer --service fansly forgotten -w 3 -e jpg
    +-------+--------------------+--------------------+---------+
    | Index |        Name        |         ID         | Service |
    +-------+--------------------+--------------------+---------+
    |   0   | forgottenlovechild | 434514358358253568 |  fansly |
    +-------+--------------------+--------------------+---------+

(back to top)

party's People

Contributors

codingcoomer avatar darkdragn avatar hornyprogrammer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

party's Issues

serverDisconnected

Traceback (most recent call last):
File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\runpy.py", line 196, in _run_module_as_main
return _run_code(code, main_globals, None,
File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\runpy.py", line 86, in run_code
exec(code, run_globals)
File "C:\Users\User\AppData\Local\Programs\Python\Python310\Scripts\party.exe_main
.py", line 7, in
File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\typer\main.py", line 214, in call
return get_command(self)(*args, **kwargs)
File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\click\core.py", line 1157, in call
return self.main(*args, **kwargs)
File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\click\core.py", line 1078, in main
rv = self.invoke(ctx)
File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\click\core.py", line 1688, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\click\core.py", line 1434, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\click\core.py", line 783, in invoke
return __callback(*args, **kwargs)
File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\typer\main.py", line 532, in wrapper
return callback(**use_params) # type: ignore
File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\party\cli.py", line 198, in coomer
pull_user(
File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\party\cli.py", line 116, in pull_user
output = asyncio.run(download_async(pbar, base_url, user.name, files, workers))
File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\asyncio\runners.py", line 44, in run
return loop.run_until_complete(main)
File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\asyncio\base_events.py", line 649, in run_until_complete
return future.result()
File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\party\cli.py", line 155, in download_async
return await asyncio.gather(*downloads)
File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\party\cli.py", line 150, in download
status = await file.download(session, filename)
File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\party\posts.py", line 71, in download
async with session.get(self.path + "?f=" + quote(self.name), headers=headers) as resp:
File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\aiohttp\client.py", line 1141, in aenter
self._resp = await self._coro
File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\aiohttp\client.py", line 560, in _request
await resp.start(conn)
File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\aiohttp\client_reqrep.py", line 899, in start
message, payload = await protocol.read() # type: ignore[union-attr]
File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\aiohttp\streams.py", line 616, in read
await self._waiter
aiohttp.client_exceptions.ServerDisconnectedError: Server disconnected

ValueError: invalid literal for int() with base 10: 'DM524874302416232448'

Unable to download from specific user shybabybun from fansly.
The example "party coomer fansly forgottenlovechild" works though so I don't understand the problem.
Trimmed log (it's too long):

PS C:\Users\************> party coomer fansly shybabybun -d "D:\#Party\shybabybun"
2023-07-26 18:55:36.782 | DEBUG    | party.cli:pull_user:74 - Ignored Extensions: []
┌─────────────────────────────── Traceback (most recent call last) ────────────────────────────────┐
│ C:\Users\************\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\ │
│ LocalCache\local-packages\Python310\site-packages\party\cli.py:228 in coomer                     │
│                                                                                                  │
│   225 │   """Convenience command for running against coomer, services[fansly,onlyfans]"""        │
│   226 │   base = "https://coomer.party"                                                          │
│   227 │   # service = "onlyfans"                                                                 │
│ > 228 │   pull_user(                                                                             │
│   229 │   │   service,                                                                           │
│   230 │   │   user_id,                                                                           │
│   231 │   │   base,                                                                              │
│                                                                                                  │
│ ┌─────────────────── locals ───────────────────┐                                                 │
│ │              base = 'https://coomer.party'   │                                                 │
│ │         directory = 'D:\\#Party\\shybabybun' │                                                 │
│ │             files = True                     │                                                 │
│ │ ignore_extensions = []                       │                                                 │
│ │             limit = None                     │                                                 │
│ │              name = None                     │                                                 │
│ │           post_id = False                    │                                                 │
│ │           service = 'fansly'                 │                                                 │
│ │           user_id = 'shybabybun'             │                                                 │
│ │           workers = 2                        │                                                 │
│ └──────────────────────────────────────────────┘                                                 │
│                                                                                                  │
│ C:\Users\************\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\ │
│ LocalCache\local-packages\Python310\site-packages\party\cli.py:138 in pull_user                  │
│                                                                                                  │
│   135 │   │   with open(f"{directory}/.embedded", "w", encoding="utf-8") as embed_file:          │
│   136 │   │   │   json.dump(embedded, embed_file)                                                │
│   137 │   with open(f"{directory}/.posts", "w", encoding="utf-8") as posts_file:                 │
│ > 138 │   │   json.dump(posts, posts_file, for_json=True)                                        │
│   139 │   typer.secho(f"Downloading from user: {user.name}", fg=typer.colors.MAGENTA)            │
│   140 │   with tqdm(total=len(files)) as pbar:                                                   │
│   141 │   │   output = asyncio.run(download_async(pbar, base_url, directory, files, workers))    │
│                                                                                                  │
│                                                                                                  │
│ C:\Users\************\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\ │
│ LocalCache\local-packages\Python310\site-packages\simplejson\__init__.py:269 in dump             │
│                                                                                                  │
│   266 │   │   │   for_json=for_json,                                                             │
│   267 │   │   │   ignore_nan=ignore_nan,                                                         │
│   268 │   │   │   int_as_string_bitcount=int_as_string_bitcount,                                 │
│ > 269 │   │   │   **kw).iterencode(obj)                                                          │
│   270 │   # could accelerate with writelines in some versions of Python, at                      │
│   271 │   # a debuggability cost                                                                 │
│   272 │   for chunk in iterable:                                                                 │
│                                                                                                  │
│                                                                                                  │
│ C:\Users\************\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\ │
│ LocalCache\local-packages\Python310\site-packages\simplejson\encoder.py:379 in iterencode        │
│                                                                                                  │
│   376 │   │   │   │   self.item_sort_key, self.encoding, self.for_json,                          │
│   377 │   │   │   │   self.iterable_as_array, Decimal=decimal.Decimal)                           │
│   378 │   │   try:                                                                               │
│ > 379 │   │   │   return _iterencode(o, 0)                                                       │
│   380 │   │   finally:                                                                           │
│   381 │   │   │   key_memo.clear()                                                               │
│   382                                                                                            │
│                                                                                                  │
│                                                                                                  │
│ C:\Users\************\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\ │
│ LocalCache\local-packages\Python310\site-packages\party\posts.py:162 in for_json                 │
│                                                                                                  │
│   159 │                                                                                          │
│   160 │   def for_json(self):                                                                    │
│   161 │   │   """Simplejson export method"""                                                     │
│ > 162 │   │   return PostSchema().dump(self)                                                     │
│   163                                                                                            │
│   164                                                                                            │
│   165 PostSchema = desert.schema_class(                                                          │
│                                                                                                  │
│                                                                                                  │
│ C:\Users\************\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\ │
│ LocalCache\local-packages\Python310\site-packages\marshmallow\schema.py:549 in dump              │
│                                                                                                  │
│    546 │   │   else:                                                                             │
│    547 │   │   │   processed_obj = obj                                                           │
│    548 │   │                                                                                     │
│ >  549 │   │   result = self._serialize(processed_obj, many=many)                                │
│    550 │   │                                                                                     │
│    551 │   │   if self._has_processors(POST_DUMP):                                               │
│    552 │   │   │   result = self._invoke_dump_processors(                                        │
│                                                                                                  │
│                                                                                                  │
│ C:\Users\************\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\ │
│ LocalCache\local-packages\Python310\site-packages\marshmallow\schema.py:517 in _serialize        │
│                                                                                                  │
│    514 │   │   │   ]                                                                             │
│    515 │   │   ret = self.dict_class()                                                           │
│    516 │   │   for attr_name, field_obj in self.dump_fields.items():                             │
│ >  517 │   │   │   value = field_obj.serialize(attr_name, obj, accessor=self.get_attribute)      │
│    518 │   │   │   if value is missing:                                                          │
│    519 │   │   │   │   continue                                                                  │
│    520 │   │   │   key = field_obj.data_key if field_obj.data_key is not None else attr_name     │
│                                                                                                  │
│                                                                                                  │
│ C:\Users\************\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\ │
│ LocalCache\local-packages\Python310\site-packages\marshmallow\fields.py:340 in serialize         │
│                                                                                                  │
│    337 │   │   │   │   return value                                                              │
│    338 │   │   else:                                                                             │
│    339 │   │   │   value = None                                                                  │
│ >  340 │   │   return self._serialize(value, attr, obj, **kwargs)                                │
│    341 │                                                                                         │
│    342 │   def deserialize(                                                                      │
│    343 │   │   self,                                                                             │
│                                                                                                  │
│                                                                                                  │
│ C:\Users\************\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\ │
│ LocalCache\local-packages\Python310\site-packages\marshmallow\fields.py:643 in _serialize        │
│                                                                                                  │
│    640 │   │   if nested_obj is None:                                                            │
│    641 │   │   │   return None                                                                   │
│    642 │   │   many = schema.many or self.many                                                   │
│ >  643 │   │   return schema.dump(nested_obj, many=many)                                         │
│    644 │                                                                                         │
│    645 │   def _test_collection(self, value):                                                    │
│    646 │   │   many = self.schema.many or self.many                                              │
│                                                                                                  │
│ ┌─────────────────────────────────────────── locals ───────────────────────────────────────────┐ │
│ │       attr = 'attachments'                                                                   │ │
│ │     kwargs = {}                                                                              │ │
│ │       many = True                                                                            │ │
│ │ nested_obj = [                                                                               │ │
│ │              │   Attachment(                                                                 │ │
│ │              │   │   filename='524872891020357632.mp4',                                      │ │
│ │              │   │   name='524872891020357632.mp4',                                          │ │
│ │              │   │                                                                           │ │
│ │              path='/be/85/be8541c511a1cad86a98426c473db6b25ee985ff227854128c84e32fa2b5f0db.… │ │
│ │              │   │   post_id='DM524874302416232448'                                          │ │
│ │              │   )                                                                           │ │
│ │              ]                                                                               │ │
│ │        obj = Post(                                                                           │ │
│ │              │   added=datetime.datetime(2023, 6, 14, 16, 53, 35),                           │ │
│ │              │   content='a lil video for free !! watch me trying to be quiet while using my │ │
│ │              nora vibrator'+32,                                                              │ │
│ │              │   edited=None,                                                                │ │
│ │              │   id='DM524874302416232448',                                                  │ │
│ │              │   published=datetime.datetime(2023, 6, 13, 5, 29, 5),                         │ │
│ │              │   service='fansly',                                                           │ │
│ │              │   shared_file=False,                                                          │ │
│ │              │   title='DM',                                                                 │ │
│ │              │   user='352820826220802048',                                                  │ │
│ │              │   attachments=[                                                               │ │
│ │              │   │   Attachment(                                                             │ │
│ │              │   │   │   filename='524872891020357632.mp4',                                  │ │
│ │              │   │   │   name='524872891020357632.mp4',                                      │ │
│ │              │   │   │                                                                       │ │
│ │              path='/be/85/be8541c511a1cad86a98426c473db6b25ee985ff227854128c84e32fa2b5f0db.… │ │
│ │              │   │   │   post_id='DM524874302416232448'                                      │ │
│ │              │   │   )                                                                       │ │
│ │              │   ],                                                                          │ │
│ │              │   embed={},                                                                   │ │
│ │              │   file=Attachment(filename=None, name=None, path=None, post_id=None)          │ │
│ │              )                                                                               │ │
│ │     schema = <Attachment(many=True)>                                                         │ │
│ │       self = <fields.Nested(dump_default=<marshmallow.missing>, attribute=None,              │ │
│ │              validate=None, required=False, load_only=False, dump_only=False,                │ │
│ │              load_default=<marshmallow.missing>, allow_none=False,                           │ │
│ │              error_messages={'required': 'Missing data for required field.', 'null': 'Field  │ │
│ │              may not be null.', 'validator_failed': 'Invalid value.', 'type': 'Invalid       │ │
│ │              type.'})>                                                                       │ │
│ └──────────────────────────────────────────────────────────────────────────────────────────────┘ │
│                                                                                                  │
│ C:\Users\************\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\ │
│ LocalCache\local-packages\Python310\site-packages\marshmallow\schema.py:549 in dump              │
│                                                                                                  │
│    546 │   │   else:                                                                             │
│    547 │   │   │   processed_obj = obj                                                           │
│    548 │   │                                                                                     │
│ >  549 │   │   result = self._serialize(processed_obj, many=many)                                │
│    550 │   │                                                                                     │
│    551 │   │   if self._has_processors(POST_DUMP):                                               │
│    552 │   │   │   result = self._invoke_dump_processors(                                        │
│                                                                                                  │
│ ┌─────────────────────────────────────────── locals ───────────────────────────────────────────┐ │
│ │          many = True                                                                         │ │
│ │           obj = [                                                                            │ │
│ │                 │   Attachment(                                                              │ │
│ │                 │   │   filename='524872891020357632.mp4',                                   │ │
│ │                 │   │   name='524872891020357632.mp4',                                       │ │
│ │                 │   │                                                                        │ │
│ │                 path='/be/85/be8541c511a1cad86a98426c473db6b25ee985ff227854128c84e32fa2b5f0… │ │
│ │                 │   │   post_id='DM524874302416232448'                                       │ │
│ │                 │   )                                                                        │ │
│ │                 ]                                                                            │ │
│ │ processed_obj = [                                                                            │ │
│ │                 │   Attachment(                                                              │ │
│ │                 │   │   filename='524872891020357632.mp4',                                   │ │
│ │                 │   │   name='524872891020357632.mp4',                                       │ │
│ │                 │   │                                                                        │ │
│ │                 path='/be/85/be8541c511a1cad86a98426c473db6b25ee985ff227854128c84e32fa2b5f0… │ │
│ │                 │   │   post_id='DM524874302416232448'                                       │ │
│ │                 │   )                                                                        │ │
│ │                 ]                                                                            │ │
│ │          self = <Attachment(many=True)>                                                      │ │
│ └──────────────────────────────────────────────────────────────────────────────────────────────┘ │
│                                                                                                  │
│ C:\Users\************\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\ │
│ LocalCache\local-packages\Python310\site-packages\marshmallow\schema.py:511 in _serialize        │
│                                                                                                  │
│    508 │   │   │   Renamed from ``marshal``.                                                     │
│    509 │   │   """                                                                               │
│    510 │   │   if many and obj is not None:                                                      │
│ >  511 │   │   │   return [                                                                      │
│    512 │   │   │   │   self._serialize(d, many=False)                                            │
│    513 │   │   │   │   for d in typing.cast(typing.Iterable[_T], obj)                            │
│    514 │   │   │   ]                                                                             │
│                                                                                                  │
│ ┌─────────────────────────────────────────── locals ───────────────────────────────────────────┐ │
│ │ many = True                                                                                  │ │
│ │  obj = [                                                                                     │ │
│ │        │   Attachment(                                                                       │ │
│ │        │   │   filename='524872891020357632.mp4',                                            │ │
│ │        │   │   name='524872891020357632.mp4',                                                │ │
│ │        │   │                                                                                 │ │
│ │        path='/be/85/be8541c511a1cad86a98426c473db6b25ee985ff227854128c84e32fa2b5f0db.mp4',   │ │
│ │        │   │   post_id='DM524874302416232448'                                                │ │
│ │        │   )                                                                                 │ │
│ │        ]                                                                                     │ │
│ │ self = <Attachment(many=True)>                                                               │ │
│ └──────────────────────────────────────────────────────────────────────────────────────────────┘ │
│                                                                                                  │
│ C:\Users\************\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\ │
│ LocalCache\local-packages\Python310\site-packages\marshmallow\schema.py:512 in <listcomp>        │
│                                                                                                  │
│    509 │   │   """                                                                               │
│    510 │   │   if many and obj is not None:                                                      │
│    511 │   │   │   return [                                                                      │
│ >  512 │   │   │   │   self._serialize(d, many=False)                                            │
│    513 │   │   │   │   for d in typing.cast(typing.Iterable[_T], obj)                            │
│    514 │   │   │   ]                                                                             │
│    515 │   │   ret = self.dict_class()                                                           │
│                                                                                                  │
│ ┌─────────────────────────────────────────── locals ───────────────────────────────────────────┐ │
│ │   .0 = <list_iterator object at 0x000001B2CBE17070>                                          │ │
│ │    d = Attachment(                                                                           │ │
│ │        │   filename='524872891020357632.mp4',                                                │ │
│ │        │   name='524872891020357632.mp4',                                                    │ │
│ │        │                                                                                     │ │
│ │        path='/be/85/be8541c511a1cad86a98426c473db6b25ee985ff227854128c84e32fa2b5f0db.mp4',   │ │
│ │        │   post_id='DM524874302416232448'                                                    │ │
│ │        )                                                                                     │ │
│ │ self = <Attachment(many=True)>                                                               │ │
│ └──────────────────────────────────────────────────────────────────────────────────────────────┘ │
│                                                                                                  │
│ C:\Users\************\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\ │
│ LocalCache\local-packages\Python310\site-packages\marshmallow\schema.py:517 in _serialize        │
│                                                                                                  │
│    514 │   │   │   ]                                                                             │
│    515 │   │   ret = self.dict_class()                                                           │
│    516 │   │   for attr_name, field_obj in self.dump_fields.items():                             │
│ >  517 │   │   │   value = field_obj.serialize(attr_name, obj, accessor=self.get_attribute)      │
│    518 │   │   │   if value is missing:                                                          │
│    519 │   │   │   │   continue                                                                  │
│    520 │   │   │   key = field_obj.data_key if field_obj.data_key is not None else attr_name     │
│                                                                                                  │
│ ┌─────────────────────────────────────────── locals ───────────────────────────────────────────┐ │
│ │ attr_name = 'post_id'                                                                        │ │
│ │ field_obj = <fields.Integer(dump_default=None, attribute=None, validate=None,                │ │
│ │             required=False, load_only=False, dump_only=False, load_default=None,             │ │
│ │             allow_none=True, error_messages={'required': 'Missing data for required field.', │ │
│ │             'null': 'Field may not be null.', 'validator_failed': 'Invalid value.',          │ │
│ │             'invalid': 'Not a valid integer.', 'too_large': 'Number too large.'})>           │ │
│ │       key = 'path'                                                                           │ │
│ │      many = False                                                                            │ │
│ │       obj = Attachment(                                                                      │ │
│ │             │   filename='524872891020357632.mp4',                                           │ │
│ │             │   name='524872891020357632.mp4',                                               │ │
│ │             │                                                                                │ │
│ │             path='/be/85/be8541c511a1cad86a98426c473db6b25ee985ff227854128c84e32fa2b5f0db.m… │ │
│ │             │   post_id='DM524874302416232448'                                               │ │
│ │             )                                                                                │ │
│ │       ret = {                                                                                │ │
│ │             │   'filename': '524872891020357632.mp4',                                        │ │
│ │             │   'name': '524872891020357632.mp4',                                            │ │
│ │             │   'path':                                                                      │ │
│ │             '/be/85/be8541c511a1cad86a98426c473db6b25ee985ff227854128c84e32fa2b5f0db.mp4'    │ │
│ │             }                                                                                │ │
│ │      self = <Attachment(many=True)>                                                          │ │
│ │     value = '/be/85/be8541c511a1cad86a98426c473db6b25ee985ff227854128c84e32fa2b5f0db.mp4'    │ │
│ └──────────────────────────────────────────────────────────────────────────────────────────────┘ │
│                                                                                                  │
│ C:\Users\************\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\ │
│ LocalCache\local-packages\Python310\site-packages\marshmallow\fields.py:340 in serialize         │
│                                                                                                  │
│    337 │   │   │   │   return value                                                              │
│    338 │   │   else:                                                                             │
│    339 │   │   │   value = None                                                                  │
│ >  340 │   │   return self._serialize(value, attr, obj, **kwargs)                                │
│    341 │                                                                                         │
│    342 │   def deserialize(                                                                      │
│    343 │   │   self,                                                                             │
│                                                                                                  │
│ ┌─────────────────────────────────────────── locals ───────────────────────────────────────────┐ │
│ │ accessor = <bound method Schema.get_attribute of <Attachment(many=True)>>                    │ │
│ │     attr = 'post_id'                                                                         │ │
│ │   kwargs = {}                                                                                │ │
│ │      obj = Attachment(                                                                       │ │
│ │            │   filename='524872891020357632.mp4',                                            │ │
│ │            │   name='524872891020357632.mp4',                                                │ │
│ │            │                                                                                 │ │
│ │            path='/be/85/be8541c511a1cad86a98426c473db6b25ee985ff227854128c84e32fa2b5f0db.mp… │ │
│ │            │   post_id='DM524874302416232448'                                                │ │
│ │            )                                                                                 │ │
│ │     self = <fields.Integer(dump_default=None, attribute=None, validate=None, required=False, │ │
│ │            load_only=False, dump_only=False, load_default=None, allow_none=True,             │ │
│ │            error_messages={'required': 'Missing data for required field.', 'null': 'Field    │ │
│ │            may not be null.', 'validator_failed': 'Invalid value.', 'invalid': 'Not a valid  │ │
│ │            integer.', 'too_large': 'Number too large.'})>                                    │ │
│ │    value = 'DM524874302416232448'                                                            │ │
│ └──────────────────────────────────────────────────────────────────────────────────────────────┘ │
│                                                                                                  │
│ C:\Users\************\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\ │
│ LocalCache\local-packages\Python310\site-packages\marshmallow\fields.py:971 in _serialize        │
│                                                                                                  │
│    968 │   │   """Return a string if `self.as_string=True`, otherwise return this field's `num_  │
│    969 │   │   if value is None:                                                                 │
│    970 │   │   │   return None                                                                   │
│ >  971 │   │   ret = self._format_num(value)  # type: _T                                         │
│    972 │   │   return self._to_string(ret) if self.as_string else ret                            │
│    973 │                                                                                         │
│    974 │   def _deserialize(self, value, attr, data, **kwargs) -> _T | None:                     │
│                                                                                                  │
│ ┌─────────────────────────────────────────── locals ───────────────────────────────────────────┐ │
│ │   attr = 'post_id'                                                                           │ │
│ │ kwargs = {}                                                                                  │ │
│ │    obj = Attachment(                                                                         │ │
│ │          │   filename='524872891020357632.mp4',                                              │ │
│ │          │   name='524872891020357632.mp4',                                                  │ │
│ │          │                                                                                   │ │
│ │          path='/be/85/be8541c511a1cad86a98426c473db6b25ee985ff227854128c84e32fa2b5f0db.mp4', │ │
│ │          │   post_id='DM524874302416232448'                                                  │ │
│ │          )                                                                                   │ │
│ │   self = <fields.Integer(dump_default=None, attribute=None, validate=None, required=False,   │ │
│ │          load_only=False, dump_only=False, load_default=None, allow_none=True,               │ │
│ │          error_messages={'required': 'Missing data for required field.', 'null': 'Field may  │ │
│ │          not be null.', 'validator_failed': 'Invalid value.', 'invalid': 'Not a valid        │ │
│ │          integer.', 'too_large': 'Number too large.'})>                                      │ │
│ │  value = 'DM524874302416232448'                                                              │ │
│ └──────────────────────────────────────────────────────────────────────────────────────────────┘ │
│                                                                                                  │
│ C:\Users\************\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\ │
│ LocalCache\local-packages\Python310\site-packages\marshmallow\fields.py:948 in _format_num       │
│                                                                                                  │
│    945 │                                                                                         │
│    946 │   def _format_num(self, value) -> typing.Any:                                           │
│    947 │   │   """Return the number value for value, given this field's `num_type`."""           │
│ >  948 │   │   return self.num_type(value)                                                       │
│    949 │                                                                                         │
│    950 │   def _validated(self, value) -> _T | None:                                             │
│    951 │   │   """Format the value or raise a :exc:`ValidationError` if an error occurs."""      │
│                                                                                                  │
│ ┌─────────────────────────────────────────── locals ───────────────────────────────────────────┐ │
│ │  self = <fields.Integer(dump_default=None, attribute=None, validate=None, required=False,    │ │
│ │         load_only=False, dump_only=False, load_default=None, allow_none=True,                │ │
│ │         error_messages={'required': 'Missing data for required field.', 'null': 'Field may   │ │
│ │         not be null.', 'validator_failed': 'Invalid value.', 'invalid': 'Not a valid         │ │
│ │         integer.', 'too_large': 'Number too large.'})>                                       │ │
│ │ value = 'DM524874302416232448'                                                               │ │
│ └──────────────────────────────────────────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘
ValueError: invalid literal for int() with base 10: 'DM524874302416232448'

Feature Request: File Size Limit Parameter

Not sure if you're taking requests or not, but could a file size parameter be added?

Some files on the party sites are massive, and I sometimes only need files up to a certain size.

Not a bug, but an issue with CLI display via SSH on MacOS

Hello,

This isn't an issue with the script itself, but rather how it's displayed.

I have party running on a Raspberry Pi which I connect to via SSH. On my Windows machines everything displays fine (via MobaXTerm, PuTTY, etc...) but Mac seems to struggle quite a bit with the text formatting and I'm wondering if anyone knows which settings I can use.

I'm currently using RoyalTSX as a terminal client using the normal Terminal plugin for SSH connections. My terminal type is set to ansi and the character encoding UTF-8

When I download something, the little spinning icon in the lower left shows, but the last frame is a question mark. Then, when it starts downloading content, the progress bar contents are just question marks and the progress bar doesn't update in-place, but rather it goes up the screen, as if whatever is being printed to the terminal is telling MacOS to go back to the start of the line (\r) and UP one line, instead of staying where it is or doing a \n to get a newline.

Does anyone else have this issue with MacOS or does anyone know how I can resolve it?

cleanup/slugify of schema fields

There are certain characters, such as "/", "\" and probably many more, that should be removed from the schema fields.
This is because they can cause unexpected behaviour, such as creating a new folder.

This may also allow the schema fields to be compatible with the Windows file system, which does not allow certain characters for folder and file names, a similar problem to #22.

ModuleNotFoundError: No module named 'pkg_resources'

Not exactly sure what I'm doing wrong, I've gotten this to work on my previous computer but now I seem unable to get it to function, here's the full error:

Traceback (most recent call last):
File "", line 198, in run_module_as_main
File "", line 88, in run_code
File "C:\Users\jack\AppData\Local\Programs\Python\Python312\Scripts\party.exe_main
.py", line 4, in
File "C:\Users\jack\AppData\Local\Programs\Python\Python312\Lib\site-packages\party\cli.py", line 18, in
from marshmallow_jsonschema import JSONSchema
File "C:\Users\jack\AppData\Local\Programs\Python\Python312\Lib\site-packages\marshmallow_jsonschema_init
.py", line 1, in
from pkg_resources import get_distribution
ModuleNotFoundError: No module named 'pkg_resources'

Help would be much appreciated.

keep getting errors

Building wheel for frozenlist (pyproject.toml) ... error
error: subprocess-exited-with-error

× Building wheel for frozenlist (pyproject.toml) did not run successfully.
│ exit code: 1
╰─> [33 lines of output]
*********************
* Accelerated build *
*********************
running bdist_wheel
running build
running build_py
creating build
creating build\lib.win-amd64-cpython-312
creating build\lib.win-amd64-cpython-312\frozenlist
copying frozenlist_init_.py -> build\lib.win-amd64-cpython-312\frozenlist
running egg_info
writing frozenlist.egg-info\PKG-INFO
writing dependency_links to frozenlist.egg-info\dependency_links.txt
writing top-level names to frozenlist.egg-info\top_level.txt
reading manifest file 'frozenlist.egg-info\SOURCES.txt'
reading manifest template 'MANIFEST.in'
warning: no previously-included files matching '.pyc' found anywhere in distribution
warning: no previously-included files matching '
.pyd' found anywhere in distribution
warning: no previously-included files matching '.so' found anywhere in distribution
warning: no previously-included files matching '
.lib' found anywhere in distribution
warning: no previously-included files matching '.dll' found anywhere in distribution
warning: no previously-included files matching '
.a' found anywhere in distribution
warning: no previously-included files matching '*.obj' found anywhere in distribution
warning: no previously-included files found matching 'frozenlist*.html'
no previously-included directories found matching 'docs_build'
adding license file 'LICENSE'
writing manifest file 'frozenlist.egg-info\SOURCES.txt'
copying frozenlist_init_.pyi -> build\lib.win-amd64-cpython-312\frozenlist
copying frozenlist_frozenlist.pyx -> build\lib.win-amd64-cpython-312\frozenlist
copying frozenlist\py.typed -> build\lib.win-amd64-cpython-312\frozenlist
running build_ext
building 'frozenlist._frozenlist' extension
error: Microsoft Visual C++ 14.0 or greater is required. Get it with "Microsoft C++ Build Tools": https://visualstudio.microsoft.com/visual-cpp-build-tools/
[end of output]

note: This error originates from a subprocess, and is likely not a problem with pip.
ERROR: Failed building wheel for frozenlist
Building wheel for multidict (pyproject.toml) ... error
error: subprocess-exited-with-error

× Building wheel for multidict (pyproject.toml) did not run successfully.
│ exit code: 1
╰─> [74 lines of output]
*********************
* Accelerated build *
*********************
running bdist_wheel
running build
running build_py
creating build
creating build\lib.win-amd64-cpython-312
creating build\lib.win-amd64-cpython-312\multidict
copying multidict_abc.py -> build\lib.win-amd64-cpython-312\multidict
copying multidict_compat.py -> build\lib.win-amd64-cpython-312\multidict
copying multidict_multidict_base.py -> build\lib.win-amd64-cpython-312\multidict
copying multidict_multidict_py.py -> build\lib.win-amd64-cpython-312\multidict
copying multidict_init_.py -> build\lib.win-amd64-cpython-312\multidict
running egg_info
writing multidict.egg-info\PKG-INFO
writing dependency_links to multidict.egg-info\dependency_links.txt
writing top-level names to multidict.egg-info\top_level.txt
reading manifest file 'multidict.egg-info\SOURCES.txt'
reading manifest template 'MANIFEST.in'
warning: no previously-included files matching '*.pyc' found anywhere in distribution
warning: no previously-included files found matching 'multidict_multidict.html'
warning: no previously-included files found matching 'multidict*.so'
warning: no previously-included files found matching 'multidict*.pyd'
warning: no previously-included files found matching 'multidict*.pyd'
no previously-included directories found matching 'docs_build'
adding license file 'LICENSE'
writing manifest file 'multidict.egg-info\SOURCES.txt'
C:\Users\zen\AppData\Local\Temp\pip-build-env-t1omj9bh\overlay\Lib\site-packages\setuptools\command\build_py.py:204: _Warning: Package 'multidict._multilib' is absent from the packages configuration.
!!

          ********************************************************************************
          ############################
          # Package would be ignored #
          ############################
          Python recognizes 'multidict._multilib' as an importable package[^1],
          but it is absent from setuptools' `packages` configuration.

          This leads to an ambiguous overall configuration. If you want to distribute this
          package, please make sure that 'multidict._multilib' is explicitly added
          to the `packages` configuration field.

          Alternatively, you can also rely on setuptools' discovery methods
          (for example by using `find_namespace_packages(...)`/`find_namespace:`
          instead of `find_packages(...)`/`find:`).

          You can read more about "package discovery" on setuptools documentation page:

          - https://setuptools.pypa.io/en/latest/userguide/package_discovery.html

          If you don't want 'multidict._multilib' to be distributed and are
          already explicitly excluding 'multidict._multilib' via
          `find_namespace_packages(...)/find_namespace` or `find_packages(...)/find`,
          you can try to use `exclude_package_data`, or `include-package-data=False` in
          combination with a more fine grained `package-data` configuration.

          You can read more about "package data files" on setuptools documentation page:

          - https://setuptools.pypa.io/en/latest/userguide/datafiles.html


          [^1]: For Python, any directory (with suitable naming) can be imported,
                even if it does not contain any `.py` files.
                On the other hand, currently there is no concept of package data
                directory, all directories are treated like packages.
          ********************************************************************************

  !!
    check.warn(importable)
  copying multidict\__init__.pyi -> build\lib.win-amd64-cpython-312\multidict
  copying multidict\py.typed -> build\lib.win-amd64-cpython-312\multidict
  running build_ext
  building 'multidict._multidict' extension
  error: Microsoft Visual C++ 14.0 or greater is required. Get it with "Microsoft C++ Build Tools": https://visualstudio.microsoft.com/visual-cpp-build-tools/
  [end of output]

note: This error originates from a subprocess, and is likely not a problem with pip.
ERROR: Failed building wheel for multidict
Building wheel for yarl (pyproject.toml) ... error
error: subprocess-exited-with-error

× Building wheel for yarl (pyproject.toml) did not run successfully.
│ exit code: 1
╰─> [49 lines of output]
C:\Users\zen\AppData\Local\Temp\pip-build-env-edueqof5\overlay\Lib\site-packages\setuptools\config\setupcfg.py:293: _DeprecatedConfig: Deprecated config in setup.cfg
!!

          ********************************************************************************
          The license_file parameter is deprecated, use license_files instead.

          This deprecation is overdue, please update your project and remove deprecated
          calls to avoid build errors in the future.

          See https://setuptools.pypa.io/en/latest/userguide/declarative_config.html for details.
          ********************************************************************************

  !!
    parsed = self.parsers.get(option_name, lambda x: x)(value)
  **********************
  * Accelerated build *
  **********************
  running bdist_wheel
  running build
  running build_py
  creating build
  creating build\lib.win-amd64-cpython-312
  creating build\lib.win-amd64-cpython-312\yarl
  copying yarl\_quoting.py -> build\lib.win-amd64-cpython-312\yarl
  copying yarl\_quoting_py.py -> build\lib.win-amd64-cpython-312\yarl
  copying yarl\_url.py -> build\lib.win-amd64-cpython-312\yarl
  copying yarl\__init__.py -> build\lib.win-amd64-cpython-312\yarl
  running egg_info
  writing yarl.egg-info\PKG-INFO
  writing dependency_links to yarl.egg-info\dependency_links.txt
  writing requirements to yarl.egg-info\requires.txt
  writing top-level names to yarl.egg-info\top_level.txt
  reading manifest file 'yarl.egg-info\SOURCES.txt'
  reading manifest template 'MANIFEST.in'
  warning: no previously-included files matching '*.pyc' found anywhere in distribution
  warning: no previously-included files matching '*.cache' found anywhere in distribution
  warning: no previously-included files found matching 'yarl\*.html'
  warning: no previously-included files found matching 'yarl\*.so'
  warning: no previously-included files found matching 'yarl\*.pyd'
  no previously-included directories found matching 'docs\_build'
  adding license file 'LICENSE'
  writing manifest file 'yarl.egg-info\SOURCES.txt'
  copying yarl\__init__.pyi -> build\lib.win-amd64-cpython-312\yarl
  copying yarl\_quoting_c.pyi -> build\lib.win-amd64-cpython-312\yarl
  copying yarl\_quoting_c.pyx -> build\lib.win-amd64-cpython-312\yarl
  copying yarl\py.typed -> build\lib.win-amd64-cpython-312\yarl
  running build_ext
  building 'yarl._quoting_c' extension
  error: Microsoft Visual C++ 14.0 or greater is required. Get it with "Microsoft C++ Build Tools": https://visualstudio.microsoft.com/visual-cpp-build-tools/
  [end of output]

note: This error originates from a subprocess, and is likely not a problem with pip.
ERROR: Failed building wheel for yarl
Failed to build frozenlist multidict yarl
ERROR: Could not build wheels for frozenlist, multidict, yarl, which is required to install pyproject.toml-based projects

i don't know why i keep getting this errors

JSON decode error

i don't know what happened here but i got this error almost instantly after running the command

Traceback (most recent call last):

  File "/home/user/.local/bin/party", line 8, in <module>
    sys.exit(APP())

  File "/home/user/.local/lib/python3.10/site-packages/party/cli.py", line 293, in coomer
    pull_user(**ctx.params)

  File "/home/user/.local/lib/python3.10/site-packages/party/cli.py", line 130, in pull_user
    user = User.get_user(site, service, user_id)

  File "/home/user/.local/lib/python3.10/site-packages/party/user.py", line 77, in get_user
    users = cls.generate_users(base_url)

  File "/home/user/.local/lib/python3.10/site-packages/party/user.py", line 48, in generate_users
    return UserSchema(context={"site": base_url}, unknown=EXCLUDE).loads(

  File "/home/user/.local/lib/python3.10/site-packages/marshmallow/schema.py", line 755, in loads
    data = self.opts.render_module.loads(json_data, **kwargs)

  File "/usr/lib/python3.10/json/__init__.py", line 346, in loads
    return _default_decoder.decode(s)

  File "/usr/lib/python3.10/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())

  File "/usr/lib/python3.10/json/decoder.py", line 353, in raw_decode
    obj, end = self.scan_once(s, idx)

json.decoder.JSONDecodeError: Unterminated string starting at: line 1 column 1404027 (char 1404026)

Python version error

I'm getting this error

ERROR: Package 'party' requires a different Python: 3.8.10 not in '>=3.9,<4.0'

I have python 3.8.10 installed but I've tried 3.11 too
Could it be an issue with python3-pip not installing the correct version?

Error when downloading fansly content from coomer

I tried to download the archive dfor different creators tha used a fansly account and get this error everytime:

Traceback (most recent call last):

  File "/home/user/.local/bin/party", line 8, in <module>
    sys.exit(APP())

  File "/home/user/.local/lib/python3.10/site-packages/party/cli.py", line 361, in search
    pull_user(

  File "/home/user/.local/lib/python3.10/site-packages/party/cli.py", line 172, in pull_user
    posts = list(

  File "/home/user/.local/lib/python3.10/site-packages/party/user.py", line 112, in generate_posts
    yield schema.load(post)

  File "/home/user/.local/lib/python3.10/site-packages/marshmallow/schema.py", line 722, in load
    return self._do_load(

  File "/home/user/.local/lib/python3.10/site-packages/marshmallow/schema.py", line 909, in _do_load
    raise exc

marshmallow.exceptions.ValidationError: {'id': ['Not a valid integer.']}

Download for Windows?

I tried running the commands for installation using cmd on Windows & Windows Power Shell after installing latest release of Phyton but can not get it to even install or run.

Error Encountered When Using 'party' Command on macOS

Issue Description:
I am encountering an error message when using the 'party' command on macOS, specifically when trying commands like 'party coomer patreon', 'party coomer kemono', and even 'party update'. The error message appears as follows:

---

User found: SelfImprovementCourse; parsing posts...https://coomer.su/api/v1/patreon/user/SelfImprovementCourse?o=0&limit=50
https://coomer.su/api/v1/patreon/user/SelfImprovementCourse?o=0&limit=50
Traceback (most recent call last):

File "/Users/[username]/Library/Python/3.9/lib/python/site-packages/requests/models.py", line 971, in json
return complexjson.loads(self.text, **kwargs)

File "/Users/[username]/Library/Python/3.9/lib/python/site-packages/simplejson/init.py", line 514, in loads
return _default_decoder.decode(s)

File "/Users/[username]/Library/Python/3.9/lib/python/site-packages/simplejson/decoder.py", line 386, in decode
obj, end = self.raw_decode(s)

File "/Users/[username]/Library/Python/3.9/lib/python/site-packages/simplejson/decoder.py", line 416, in raw_decode
return self.scan_once(s, idx=_w(s, idx).end())

simplejson.errors.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):

File "/Users/[username]/Library/Python/3.9/bin/party", line 8, in
sys.exit(APP())

File "/Users/[username]/Library/Python/3.9/lib/python/site-packages/party/cli.py", line 441, in update
pull_user(

File "/Users/[username]/Library/Python/3.9/lib/python/site-packages/party/cli.py", line 155, in pull_user
posts = list(user.limit_posts(limit))

File "/Users/[username]/Library/Python/3.9/lib/python/site-packages/party/user.py", line 99, in generate_posts
raise e

File "/Users/[username]/Library/Python/3.9/lib/python/site-packages/party/user.py", line 93, in generate_posts
posts = resp.json()

File "/Users/[username]/Library/Python/3.9/lib/python/site-packages/requests/models.py", line 975, in json
raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)

requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

---

or sometimes i get this error other message:

---

User found: SelfImprovementCourse; parsing posts...https://coomer.su/api/v1/patreon/user/SelfImprovementCourse?o=0&limit=50
https://coomer.su/api/v1/patreon/user/SelfImprovementCourse?o=0&limit=50
Traceback (most recent call last):

File "/Users/[username]/Library/Python/3.9/lib/python/site-packages/requests/models.py", line 971, in json
return complexjson.loads(self.text, **kwargs)

File "/Users/[username]/Library/Python/3.9/lib/python/site-packages/simplejson/init.py", line 514, in loads
return _default_decoder.decode(s)

File "/Users/[username]/Library/Python/3.9/lib/python/site-packages/simplejson/decoder.py", line 386, in decode
obj, end = self.raw_decode(s)

File "/Users/[username]/Library/Python/3.9/lib/python/site-packages/simplejson/decoder.py", line 416, in raw_decode
return self.scan_once(s, idx=_w(s, idx).end())

simplejson.errors.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):

File "/Users/[username]/Library/Python/3.9/bin/party", line 8, in
sys.exit(APP())

File "/Users/[username]/Library/Python/3.9/lib/python/site-packages/party/cli.py", line 441, in update
pull_user(

File "/Users/[username]/Library/Python/3.9/lib/python/site-packages/party/cli.py", line 155, in pull_user
posts = list(user.limit_posts(limit))

File "/Users/[username]/Library/Python/3.9/lib/python/site-packages/party/user.py", line 99, in generate_posts
raise e

File "/Users/[username]/Library/Python/3.9/lib/python/site-packages/party/user.py", line 93, in generate_posts
posts = resp.json()

File "/Users/[username]/Library/Python/3.9/lib/python/site-packages/requests/models.py", line 975, in json
raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)

requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

---

Steps to Reproduce:

  1. Open terminal on macOS.
  2. Execute the command 'party coomer patreon'.
  3. Observe the error message.

Expected Behavior:
I expect the 'party' command to execute successfully without encountering JSON decoding errors.

Environment:

  1. Operating System: macOS
  2. Python Version: Python 3.9.6
  3. Command Used: 'party coomer patreon [username]', 'party coomer kemono [username]', 'party update [username]'

Additional Information:

  • This issue occurs consistently whenever the mentioned commands are executed.
  • I have tried updating the 'party' tool and dependencies but the issue persists.

Any assistance or guidance on resolving this issue would be greatly appreciated.

Thank you.

I am new

Hi there I am new to gitgub and I have no clue what should I do
I tried to follow what was in the description but I can't understand what should I do in python
can I get like a small tutorial how to download from coomer
Thanls

Download location

Hello,
I am using this application on ubuntu and am wondering where the download location is.

Thanks

Kemono not working for some services where id isn't numeric

Solution:
in user.py -> User -> get_user(...)
the return should be

   try:
        attr = "id"
        return next(
            (i for i in users if i.service == service and getattr(i, attr) == search)
        )
    except StopIteration:
        attr = "name"
        return next(
            (i for i in users if i.service == service and getattr(i, attr) == search)
        )

and remove attr = "id" if search.isnumeric() else "name"
Why? Some of the new services have ids which are not numeric. Therefore this starts with id as default, if it doesn't work then moves to using the name attribute. After testing it on my own this works. This doesn't fix all the services as some still don't like to work but it fixes the ones where id isn't number

tldr: make user.py User.get_user(...) the following

@classmethod
def get_user(cls, base_url: str, service: str, search: str):
    """Return a User object from a match against service and search.

    Args:
        base_url: kemono.party or coomer.party
        service: { kemono: [patreon, fanbox, fantia, etc...], coomer: [onlyfans]}
        search: user id or user name
    Returns:
        User
    """
    users = cls.generate_users(base_url)
    try:
        attr = "id"
        return next(
            (i for i in users if i.service == service and getattr(i, attr) == search)
        )
    except StopIteration:
        attr = "name"
        return next(
            (i for i in users if i.service == service and getattr(i, attr) == search)
        )

SSL Error

When I use the party search anaimiya coomer -i to download this blogger's posts, after a while it reports an SSL error. When I use the party update anaimiya command to update again, it will report an error directly.

The error message is as follows:
`(PartyDownloader) F:\coomer>party update anaimiya
2023-08-27 18:03:55.010 | DEBUG | party.cli:pull_user:80 - Excluded Extensions: []
urllib3.exceptions.SSLError: [SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:1002)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):

File "C:\Users\user\anaconda3\envs\PartyDownloader\Lib\site-packages\requests\adapters.py", line 486, in send
resp = conn.urlopen(
^^^^^^^^^^^^^

File "C:\Users\user\anaconda3\envs\PartyDownloader\Lib\site-packages\urllib3\connectionpool.py", line 844, in urlopen
retries = retries.increment(
^^^^^^^^^^^^^^^^^^

File "C:\Users\user\anaconda3\envs\PartyDownloader\Lib\site-packages\urllib3\util\retry.py", line 515, in increment
raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='coomer.party', port=443): Max retries exceeded with url: /api/onlyfans/user/anaimiya?o=250&limit=50 (Caused by SSLError(SSLEOFError(8, '[SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:1002)')))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):

File "", line 198, in _run_module_as_main

File "", line 88, in _run_code

File "C:\Users\user\anaconda3\envs\PartyDownloader\Scripts\party.exe_main_.py", line 7, in
sys.exit(APP())
^^^^^

File "C:\Users\user\anaconda3\envs\PartyDownloader\Lib\site-packages\party\cli.py", line 363, in update
pull_user(

File "C:\Users\user\anaconda3\envs\PartyDownloader\Lib\site-packages\party\cli.py", line 106, in pull_user
embedded = [embed for p in user.posts if (embed := p.embed)]
^^^^^^^^^^

File "C:\Users\user\anaconda3\envs\PartyDownloader\Lib\functools.py", line 1001, in get
val = self.func(instance)
^^^^^^^^^^^^^^^^^^^

File "C:\Users\user\anaconda3\envs\PartyDownloader\Lib\site-packages\party\user.py", line 133, in posts
return list(self.generate_posts())
^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "C:\Users\user\anaconda3\envs\PartyDownloader\Lib\site-packages\party\user.py", line 82, in generate_posts
resp = requests.get(self.url, params=dict(o=offset, limit=50))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "C:\Users\user\anaconda3\envs\PartyDownloader\Lib\site-packages\requests\api.py", line 73, in get
return request("get", url, params=params, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "C:\Users\user\anaconda3\envs\PartyDownloader\Lib\site-packages\requests\api.py", line 59, in request
return session.request(method=method, url=url, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "C:\Users\user\anaconda3\envs\PartyDownloader\Lib\site-packages\requests\sessions.py", line 589, in request
resp = self.send(prep, **send_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "C:\Users\user\anaconda3\envs\PartyDownloader\Lib\site-packages\requests\sessions.py", line 703, in send
r = adapter.send(request, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "C:\Users\user\anaconda3\envs\PartyDownloader\Lib\site-packages\requests\adapters.py", line 517, in send
raise SSLError(e, request=request)

requests.exceptions.SSLError: HTTPSConnectionPool(host='coomer.party', port=443): Max retries exceeded with url: /api/onlyfans/user/anaimiya?o=250&limit=50 (Caused by SSLError(SSLEOFError(8, '[SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:1002)')))

(PartyDownloader) F:\coomer>party update anaimiya
2023-08-27 18:09:30.959 | DEBUG | party.cli:pull_user:80 - Excluded Extensions: []
urllib3.exceptions.SSLError: [SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:1002)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):

File "C:\Users\user\anaconda3\envs\PartyDownloader\Lib\site-packages\requests\adapters.py", line 486, in send
resp = conn.urlopen(
^^^^^^^^^^^^^

File "C:\Users\user\anaconda3\envs\PartyDownloader\Lib\site-packages\urllib3\connectionpool.py", line 844, in urlopen
retries = retries.increment(
^^^^^^^^^^^^^^^^^^

File "C:\Users\user\anaconda3\envs\PartyDownloader\Lib\site-packages\urllib3\util\retry.py", line 515, in increment
raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='coomer.party', port=443): Max retries exceeded with url: /api/onlyfans/user/anaimiya?o=0&limit=50 (Caused by SSLError(SSLEOFError(8, '[SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:1002)')))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):

File "", line 198, in _run_module_as_main

File "", line 88, in _run_code

File "C:\Users\user\anaconda3\envs\PartyDownloader\Scripts\party.exe_main_.py", line 7, in
sys.exit(APP())
^^^^^

File "C:\Users\user\anaconda3\envs\PartyDownloader\Lib\site-packages\party\cli.py", line 363, in update
pull_user(

File "C:\Users\user\anaconda3\envs\PartyDownloader\Lib\site-packages\party\cli.py", line 105, in pull_user
posts = list(user.limit_posts(limit))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "C:\Users\user\anaconda3\envs\PartyDownloader\Lib\site-packages\party\user.py", line 82, in generate_posts
resp = requests.get(self.url, params=dict(o=offset, limit=50))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "C:\Users\user\anaconda3\envs\PartyDownloader\Lib\site-packages\requests\api.py", line 73, in get
return request("get", url, params=params, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "C:\Users\user\anaconda3\envs\PartyDownloader\Lib\site-packages\requests\api.py", line 59, in request
return session.request(method=method, url=url, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "C:\Users\user\anaconda3\envs\PartyDownloader\Lib\site-packages\requests\sessions.py", line 589, in request
resp = self.send(prep, **send_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "C:\Users\user\anaconda3\envs\PartyDownloader\Lib\site-packages\requests\sessions.py", line 703, in send
r = adapter.send(request, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "C:\Users\user\anaconda3\envs\PartyDownloader\Lib\site-packages\requests\adapters.py", line 517, in send
raise SSLError(e, request=request)

requests.exceptions.SSLError: HTTPSConnectionPool(host='coomer.party', port=443): Max retries exceeded with url: /api/onlyfans/user/anaimiya?o=0&limit=50 (Caused by SSLError(SSLEOFError(8, '[SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:1002)')))`

Not a issue but a basic gui

Hi,

i Have made a basic gui for Party.
it still requires party to be installed along with PySimpleGui, it doesn't have full functionality for kemono yet but it works fine for coomer.

just if you want to i can send you it.

the only i ask is if you will use it for the publick party i want to have credits on like the github page.

Bye :3

Connection Timeout Error

Got this error
requests.exceptions.ConnectTimeout: HTTPSConnectionPool(host='coomer.su', port=443): Max retries exceeded with url: /api/v1/creators.txt (Caused by ConnectTimeoutError(<urllib3.connection.HTTPSConnection object at 0x0000011A7CFDADB0>, 'Connection to coomer.su timed out. (connect timeout=90)'))

I got this error

NotOpenSSLWarning: urllib3 v2.0 only supports OpenSSL 1.1.1+, currently the 'ssl' module is compiled with 'LibreSSL 2.8.3'.

It should be noted that I got this error occurred just recently. I was using it since last month and never got this error before. The command used to work well in the past. If it helps in anything, i am using mac

SSL Error

I get this when I try to download

File "C:\Users\Zonic\AppData\Local\Programs\Python\Python312\Lib\site-packages\aiohttp\connector.py", line 1025, in _wrap_create_connection
return await self._loop.create_connection(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "C:\Users\Zonic\AppData\Local\Programs\Python\Python312\Lib\asyncio\base_events.py", line 1149, in create_connection
transport, protocol = await self._create_connection_transport(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "C:\Users\Zonic\AppData\Local\Programs\Python\Python312\Lib\asyncio\base_events.py", line 1182, in _create_connection_transport
await waiter

File "C:\Users\Zonic\AppData\Local\Programs\Python\Python312\Lib\asyncio\sslproto.py", line 578, in _on_handshake_complete
raise handshake_exc

File "C:\Users\Zonic\AppData\Local\Programs\Python\Python312\Lib\asyncio\sslproto.py", line 560, in _do_handshake
self._sslobj.do_handshake()

File "C:\Users\Zonic\AppData\Local\Programs\Python\Python312\Lib\ssl.py", line 917, in do_handshake
self._sslobj.do_handshake()

ssl.SSLError: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1000)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):

File "", line 198, in _run_module_as_main

File "", line 88, in _run_code

File "C:\Users\Zonic\AppData\Local\Programs\Python\Python312\Scripts\party.exe_main_.py", line 7, in
sys.exit(APP())
^^^^^

File "C:\Users\Zonic\AppData\Local\Programs\Python\Python312\Lib\site-packages\party\cli.py", line 286, in kemono
pull_user(**ctx.params)

File "C:\Users\Zonic\AppData\Local\Programs\Python\Python312\Lib\site-packages\party\cli.py", line 211, in pull_user
output = asyncio.run(
^^^^^^^^^^^^

File "C:\Users\Zonic\AppData\Local\Programs\Python\Python312\Lib\asyncio\runners.py", line 194, in run
return runner.run(main)
^^^^^^^^^^^^^^^^

File "C:\Users\Zonic\AppData\Local\Programs\Python\Python312\Lib\asyncio\runners.py", line 118, in run
return self._loop.run_until_complete(task)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "C:\Users\Zonic\AppData\Local\Programs\Python\Python312\Lib\asyncio\base_events.py", line 687, in run_until_complete
return future.result()
^^^^^^^^^^^^^^^

File "C:\Users\Zonic\AppData\Local\Programs\Python\Python312\Lib\site-packages\party\cli.py", line 269, in download_async
temp = await asyncio.gather(*downloads)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "C:\Users\Zonic\AppData\Local\Programs\Python\Python312\Lib\site-packages\party\cli.py", line 252, in download
status = await file.download(
^^^^^^^^^^^^^^^^^^^^

File "C:\Users\Zonic\AppData\Local\Programs\Python\Python312\Lib\site-packages\party\posts.py", line 140, in download
async with session.head(url, allow_redirects=True) as head:

File "C:\Users\Zonic\AppData\Local\Programs\Python\Python312\Lib\site-packages\aiohttp\client.py", line 1197, in aenter
self._resp = await self._coro
^^^^^^^^^^^^^^^^

File "C:\Users\Zonic\AppData\Local\Programs\Python\Python312\Lib\site-packages\aiohttp\client.py", line 581, in _request
conn = await self._connector.connect(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "C:\Users\Zonic\AppData\Local\Programs\Python\Python312\Lib\site-packages\aiohttp\connector.py", line 544, in connect
proto = await self._create_connection(req, traces, timeout)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "C:\Users\Zonic\AppData\Local\Programs\Python\Python312\Lib\site-packages\aiohttp\connector.py", line 944, in _create_connection
_, proto = await self._create_direct_connection(req, traces, timeout)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "C:\Users\Zonic\AppData\Local\Programs\Python\Python312\Lib\site-packages\aiohttp\connector.py", line 1257, in _create_direct_connection
raise last_exc

File "C:\Users\Zonic\AppData\Local\Programs\Python\Python312\Lib\site-packages\aiohttp\connector.py", line 1226, in _create_direct_connection
transp, proto = await self._wrap_create_connection(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "C:\Users\Zonic\AppData\Local\Programs\Python\Python312\Lib\site-packages\aiohttp\connector.py", line 1029, in _wrap_create_connection
raise ClientConnectorSSLError(req.connection_key, exc) from exc

aiohttp.client_exceptions.ClientConnectorSSLError: Cannot connect to host c2.kemono.su:443 ssl:default [[SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1000)]

Sequential filename renaming (Feature Request)

Hi, been using this tool for a bit, I'd like to request the ability for the tool to rename files in the order that they are ordered in the actual post.
I'm not sure if I'm missing something, but downloaded files have the "hashed" filenames, like so:
8q60e129-83d0-4108-a4dc-17b41f230d91.jpg

These don't really sort nicely. I see there is an option to prepend the post ID before the filename via --post-id, which helps, but some posts have multiple images in them, like comic pages, and even with the post ID these pages may not sort properly due to the random nature of the filenames.

  1. Page 1: 123456_f70613de-5279-469a-acb7-64e56eqf6093.png
  2. Page 2: 123456_c8b52368-fff3-4f3c-q69c-6678d1443817.png

As above, images named like so will result in page 2 coming before page 1.

My request would be just an option of some sort, maybe --ordered that is used in conjunction with --post-id that pre-pends the image's order in the post so the filenames becomes like something of the following:

  • 123456_001.png, or
  • 123456_001_f70613de-5279-469a-acb7-64e56eqf6093.png

Hope that is clear, thanks!

Issue downloading only one certain user

First off, thank you very much for this program, it's incredibly useful!
So far the program is working flawlessly for me for both kemono and coomer.. except for one profile. I'm not sure why, but every time it gives me this message after "Pulling User ID" for a few seconds:
image

Also side note, is there a way to change the default download directory? I saw that someone else asked about this back in January but didn't see any documentation on how to actually change it, and the last release was in October so I'm assuming it just hasn't been added yet, correct?

SSL Error on Coomer

Hey, thank you for creating this nice tool.
But I can't use it because of an SSL error. The site coomer.su works well in Safari and Chrome. I can view the posts and download images and videos manually, even it's a bit slow.
I'm using MacOS 13.4.1 and python 3.12.2.

Can you please help?

% party coomer onlyfans jennys_passion
Downloading from user: jennys_passion
0%| | 0/874 [00:00<?, ?it/s]
Traceback (most recent call last):

File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/aiohttp/connector.py", line 992, in _wrap_create_connection
return await self._loop.create_connection(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/base_events.py", line 1147, in create_connection
transport, protocol = await self._create_connection_transport(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/base_events.py", line 1180, in _create_connection_transport
await waiter

File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/sslproto.py", line 578, in _on_handshake_complete
raise handshake_exc

File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/sslproto.py", line 560, in _do_handshake
self._sslobj.do_handshake()

File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/ssl.py", line 917, in do_handshake
self._sslobj.do_handshake()

ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1000)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):

File "/Library/Frameworks/Python.framework/Versions/3.12/bin/party", line 8, in
sys.exit(APP())
^^^^^

File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/party/cli.py", line 293, in coomer
pull_user(**ctx.params)

File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/party/cli.py", line 211, in pull_user
output = asyncio.run(
^^^^^^^^^^^^

File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/runners.py", line 194, in run
return runner.run(main)
^^^^^^^^^^^^^^^^

File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/runners.py", line 118, in run
return self._loop.run_until_complete(task)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/base_events.py", line 685, in run_until_complete
return future.result()
^^^^^^^^^^^^^^^

File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/party/cli.py", line 269, in download_async
temp = await asyncio.gather(*downloads)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/party/cli.py", line 252, in download
status = await file.download(
^^^^^^^^^^^^^^^^^^^^

File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/party/posts.py", line 140, in download
async with session.head(url, allow_redirects=True) as head:

File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/aiohttp/client.py", line 1194, in aenter
self._resp = await self._coro
^^^^^^^^^^^^^^^^

File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/aiohttp/client.py", line 578, in _request
conn = await self._connector.connect(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/aiohttp/connector.py", line 544, in connect
proto = await self._create_connection(req, traces, timeout)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/aiohttp/connector.py", line 911, in _create_connection
_, proto = await self._create_direct_connection(req, traces, timeout)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/aiohttp/connector.py", line 1235, in _create_direct_connection
raise last_exc

File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/aiohttp/connector.py", line 1204, in _create_direct_connection
transp, proto = await self._wrap_create_connection(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/aiohttp/connector.py", line 994, in _wrap_create_connection
raise ClientConnectorCertificateError(req.connection_key, exc) from exc

aiohttp.client_exceptions.ClientConnectorCertificateError: Cannot connect to host coomer.su:443 ssl:True [SSLCertVerificationError: (1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1000)')]

Partial downloads

I am using party coomer .. and it downloads all posts but many (may be 40%) of the posts are partial. Video only plays half and then player crashes.

I tried with -w 1 but no improvement.

Error with emoji's

Hi I am trying to download content from coomer (onlyfans) using this tool, but i am getting an error that emoji's probably can't be parsed.

final = False │ │
│ │ input = '[{"id":"790805353","user":"vaniitys","service":"onlyfans","title":"🎃HAPPY │ │
│ │ HALLOW'+25238 │ │
│ │ self = <encodings.cp1252.IncrementalEncoder object at 0x000001DF1F948650>

UnicodeEncodeError: 'charmap' codec can't encode character '\U0001f383' in position 67: character maps to undefined

I tried with --post-id and --no-post-title but that didn't work sadly enough.

missing files when using --file-format "{ref.post_id}.{ref.extension}"

I downloaded someone by using <party coomer onlyfans userID --file-format "{ref.post_id}.{ref.extension}">,
found missing many photos and the total file counting is 86,
so I try to use the common command ,
it all come back and the total file counting is 170,
but if I use this command the filename seem not sorting by post date,
is this a bug?

2023-11-25_224314

what command should I use if I want the file name sort by post date and keep downloading all files?
and what is the command <--sluglify> in the end used for?

Feature Request: Using Post Title as Filename

Is it possible to use the post title or the post content as the files name that is downloaded? It just makes it a bit easier to search. I tried doing it myself but had no success.

Can't download today ...

tried to download 2 accounts today,
but always result like below:

2024-02-05_164843
it is ok a couple days ago,
can you help?

Thanks.

I got this error

ClientConnectorCertificateError: Cannot connect to host coomer.party:443
ssl:True [SSLCertVerificationError: (1, '[SSL: CERTIFICATE_VERIFY_FAILED]
certificate verify failed: unable to get local issuer certificate
(_ssl.c:997)')]

Is that a solution to solve this?

JSONDecodeError

Hi, I get

"JSONDecodeError: Expecting value: line 1 column 1 (char 0)"

when indexing all posts of user "emmamagnoliaxo".

The error occurs even before the first download starts. Other creators work fine.

user found but parsing posts forever ... :(

I just use it downloaded one onlyfans and all 129 GB completed perfectly,
but when I want to use the same command to download another one,
it just parsing forever like below:

2023-11-14_193812

changed another target results the same,
changed back to original download path still,
any solution?
Many thanks!!!!!!!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.