Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Async DLsite API for fetching work metadata
comic
)home
, Adult/maniax
)books
)soft
)pro
)appx
)Async DLsite Play API
optimized
file versions can be downloadeddlsite-async[pil]
You can install DLsite Async via pip from PyPI:
$ pip install dlsite-async
Certain features require may installing extra dependencies:
$ pip install dlsite-async[pil]
Fetch manga information:
>>> import asyncio
>>> from dlsite_async import DlsiteAPI
>>> async def f():
... async with DlsiteAPI() as api:
... return await api.get_work("BJ370220")
...
>>> asyncio.run(f())
Work(
product_id='BJ370220',
site_id='comic',
maker_id='BG01675',
work_name='衛宮さんちの今 日のごはん (6)\u3000レシピ本付特装版',
age_category=<AgeCategory.ALL_AGES: 1>,
circle=None,
brand=None,
publisher='KADOKAWA',
work_image='//img.dlsite.jp/.../BJ370220_img_main.jpg',
regist_date=datetime.datetime(2021, 10, 28, 0, 0),
work_type=<WorkType.MANGA: 'MNG'>,
book_type=<BookType.BOOK: 'comic'>,
...
author=['TAa', '只野まこと', 'TYPE−MOON'],
...
genre=['少年コミック', 'ギャグ', 'コメディ', 'ほのぼの'],
label='KADOKAWA',
...
page_count=307
)
Fetch English voice/ASMR information:
>>> async def f():
... async with DlsiteAPI(locale="en_US") as api:
... return await api.get_work("RJ294126")
...
>>> asyncio.run(f())
Work(
product_id='RJ294126',
site_id='maniax',
maker_id='RG51931',
work_name='Pure Pussy on Duty',
age_category=<AgeCategory.R18: 3>,
circle='aoharu fetishism',
brand=None,
publisher=None,
work_image='//img.dlsite.jp/.../RJ294126_img_main.jpg',
regist_date=datetime.datetime(2020, 8, 30, 0, 0),
work_type=<WorkType.VOICE_ASMR: 'SOU'>,
...
illustration=['ぬこぷし'],
voice_actor=['逢坂成美'],
...
genre=['Healing', 'Dirty Talk', 'Binaural', 'ASMR', ...],
...
file_format=['WAV'],
file_size='Total 010.63GB',
...
)
List DLsite Play files in a work:
>>> from dlsite_async import PlayAPI
>>> async def f():
... async with PlayAPI() as play_api:
... await play_api.login("username", "password")
... token = await play_api.download_token("RJ294126")
... tree = await play_api.ziptree(token)
... return dict(tree.items())
...
>>> asyncio.run(f())
{
'純愛おま○こ当番【アップデート版】/readme.txt': PlayFile(
length=4006,
type='text',
files={
'optimized': {
'encoding': 'UTF-8',
'length': 5232,
'name': '95b8dd8e45a2ff0b1d45717b93a096b7.txt',
'size': '5.1KB'
}
}
),
...,
'純愛おま○こ当番【アップデート版】/02_wav/track00_タイトルコール.wav' PlayFile(
length=5193978,
type='audio',
files={
'optimized': {
'bit_rate': 74182,
'duration': 6.768,
'length': 62758,
'name': '069498e95c11ad47fc65ee87a1a0ae60.mp3',
'size': '61.3KB'
}
}
),
...,
'純愛おま○こ当番【アップデート版】/04_omake/01:高画質画像/junai_r_01.jpg': PlayFile(
length=1394068,
type='image',
files={
'files': {
'crypt': False,
'height': 3000,
'length': 1394068,
'name': 'd0b8bc7a93e4f1c4c3d5e3eed6d65393.jpg',
'size': '1.3MB',
'width': 2143
},
'optimized': {
'crypt': True,
'height': 1280,
'length': 220746,
'name': 'd0b8bc7a93e4f1c4c3d5e3eed6d65393.jpg',
'size': '215.6KB',
'width': 914
}
}
),
...,
'純愛おま○こ当番【アップデート版】/05_字幕付き音声動画/trackEX_おま○こ当番と体育倉庫でナイショえっち.mp4': PlayFile(
length=297495132,
type='video',
files={
'files': {
'frame_rate': '24/1',
'height': 1080,
'width': 1920
},
'optimized': {
'duration': '1004.693333',
'name': 'd5e47f10d9d98944f6d4003497087c53.m3u8',
'streams': ['v720p', 'v480p', 'v240p']
}
}
),
...,
}
Download web-optimized images from a manga/comic work to the current working directory
(Note that using descramble=True
requires dlsite_async[pil]
):
>>> import os
>>> import asyncio
>>> from dlsite_async import PlayAPI
>>> async def f():
... async with PlayAPI() as play_api:
... await play_api.login(username, password)
... token = await play_api.download_token("BJ277832")
... tree = await play_api.ziptree(token)
... for filename, playfile in tree.items():
... if playfile.type != "image":
... continue
... orig_path, _ = os.path.splitext(filename)
... _, ext = os.path.splitext(playfile.optimized_name)
... dest = f"{orig_path}{ext}"
... await play_api.download_playfile(
... token, playfile, dest, mkdir=True, descramble=True
... )
...
>>> asyncio.run(f())
List purchased works in order of purchase:
>>> import asyncio
>>> from dlsite_async import PlayAPI
>>> async def f():
... async with PlayAPI() as play_api:
... await play_api.login(username, password)
... return sorted(
... [
... (work, purchase_date)
... async for work, purchase_date in play_api.purchases()
... ],
... key=lambda p: p[1],
... )
...
>>> asyncio.run(f())
[(Work(...), datetime.datetime(2014, 7, 7, 4, 47, 6, tzinfo=datetime.timezone.utc)),
...
(Work(...), datetime.datetime(2024, 7, 16, 14, 55, 40, tzinfo=datetime.timezone.utc)),]
Contributions are very welcome. To learn more, see the Contributor Guide.
Distributed under the terms of the MIT license, DLsite Async is free and open source software.
If you encounter any problems, please file an issue along with a detailed description.
This project was generated from @cjolowicz's Hypermodern Python Cookiecutter template.
FAQs
DLsite Async
We found that dlsite-async demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.