Skip to content

Commit

Permalink
Merge pull request #57 from niconicolibs/develop
Browse files Browse the repository at this point in the history
release: v2.0.6
  • Loading branch information
Negima1072 authored Aug 18, 2024
2 parents 6cdd165 + fb80f34 commit b2feaac
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 29 deletions.
6 changes: 5 additions & 1 deletion examples/download.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
"""Example of downloading a video."""

import logging

from niconico import NicoNico

logging.basicConfig(level=logging.DEBUG, format="%(message)s")

client = NicoNico()

watch_data = client.video.watch.get_watch_data("sm9")

outputs = client.video.watch.get_outputs(watch_data)
output_label = next(iter(outputs))

downloaded_path = client.video.watch.download_video(watch_data, output_label, ".")
downloaded_path = client.video.watch.download_video(watch_data, output_label, "%(title)s.%(ext)s")

print(downloaded_path)
2 changes: 1 addition & 1 deletion niconico/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
from niconico.niconico import NicoNico

__all__ = ("NicoNico",)
__version__ = "2.0.5"
__version__ = "2.0.6"
52 changes: 27 additions & 25 deletions niconico/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,78 +7,80 @@
from niconico import NicoNico, __version__
from niconico.exceptions import LoginFailureError, WatchAPIError

logger = logging.getLogger("niconico.py")


def command_details(args: argparse.Namespace) -> None:
"""Show video details."""
logging.debug("Starting command: details with args: %s", args)
logger.debug("Starting command: details with args: %s", args)
client = NicoNico()
video = client.video.get_video(args.id)
if video is None:
logging.error("Video not found")
logger.error("Video not found")
return
logging.debug("Video: %s", video)
logger.debug("Video: %s", video)
if args.output is None:
logging.info(video.model_dump_json(indent=2, by_alias=True))
logger.info(video.model_dump_json(indent=2, by_alias=True))
else:
with args.output.open("w") as f:
f.write(video.model_dump_json(by_alias=True))
logging.info("Saved to %s", args.output)
logger.info("Saved to %s", args.output)


def command_quality(args: argparse.Namespace) -> None:
"""Show video quality."""
logging.debug("Starting command: quality with args: %s", args)
logger.debug("Starting command: quality with args: %s", args)
client = NicoNico()
if args.session is not None:
try:
client.login_with_session(args.session)
logging.debug("Logged in with session")
logger.debug("Logged in with session")
except LoginFailureError:
logging.exception("Login failed")
logging.debug("is_premium: %s", client.premium)
logger.exception("Login failed")
logger.debug("is_premium: %s", client.premium)
try:
watch_data = client.video.watch.get_watch_data(args.id)
except WatchAPIError:
logging.exception("An error has occurred")
logger.exception("An error has occurred")
return
logging.debug("Watch data: %s", watch_data)
logger.debug("Watch data: %s", watch_data)
outputs = client.video.watch.get_outputs(watch_data)
logging.info("Label\tVideo, Audio")
logger.info("Label\tVideo, Audio")
for output_key, output in outputs.items():
logging.info("%s:\t%s", output_key, ", ".join(output))
logger.info("%s:\t%s", output_key, ", ".join(output))


def command_download(args: argparse.Namespace) -> None:
"""Download video."""
logging.debug("Starting command: download with args: %s", args)
logger.debug("Starting command: download with args: %s", args)
client = NicoNico()
if args.session is not None:
try:
client.login_with_session(args.session)
logging.debug("Logged in with session")
logger.debug("Logged in with session")
except LoginFailureError:
logging.exception("Login failed")
logging.debug("is_premium: %s", client.premium)
logger.exception("Login failed")
logger.debug("is_premium: %s", client.premium)
try:
watch_data = client.video.watch.get_watch_data(args.id)
except WatchAPIError:
logging.exception("An error has occurred")
logger.exception("An error has occurred")
return
logging.debug("Watch data: %s", watch_data)
logger.debug("Watch data: %s", watch_data)
outputs = client.video.watch.get_outputs(watch_data)
logging.debug("Outputs: %s", outputs)
logger.debug("Outputs: %s", outputs)
if args.quality is not None:
if args.quality not in outputs:
logging.error("This quality is not supported")
logger.error("This quality is not supported")
return
quality = args.quality
logging.debug("Selected quality: %s", quality)
logger.debug("Selected quality: %s", quality)
else:
quality = next(iter(outputs))
logging.debug("Selected quality: %s(best)", quality)
logging.debug("Downloading video...")
logger.debug("Selected quality: %s(best)", quality)
logger.debug("Downloading video...")
downloaded_path = client.video.watch.download_video(watch_data, quality, args.output)
logging.info("Downloaded to %s", downloaded_path)
logger.info("Downloaded to %s", downloaded_path)


def main() -> None:
Expand Down
4 changes: 4 additions & 0 deletions niconico/base/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,7 @@ class BaseClient:
def __init__(self, niconico: NicoNico) -> None:
"""Initialize the base client."""
self.niconico = niconico

def log(self, type_: str, message: str) -> None:
"""Log a message."""
return getattr(self.niconico.logger, type_)(message)
6 changes: 6 additions & 0 deletions niconico/niconico.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,21 @@

from __future__ import annotations

from logging import Logger, getLogger

import requests

from niconico.exceptions import LoginFailureError
from niconico.user import UserClient
from niconico.video import VideoClient

logger = getLogger("niconico.py")


class NicoNico:
"""A class to interact with the NicoNico API."""

logger: Logger
session: requests.Session
logined: bool
premium: bool
Expand All @@ -21,6 +26,7 @@ class NicoNico:

def __init__(self) -> None:
"""Initialize the class."""
self.logger = logger
self.session = requests.Session()
self.logined = False
self.video = VideoClient(self)
Expand Down
9 changes: 8 additions & 1 deletion niconico/video/watch.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,14 @@ def download_video(self, watch_data: WatchData, output_label: str, output_path:
],
)
try:
with subprocess.Popen(commands, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, text=True) as p: # noqa: S602
with subprocess.Popen( # noqa: S602
commands,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
shell=True,
) as p:
for line in iter(p.stdout.readline, b""): # type: ignore[union-attr]
self.log("debug", line.rstrip())
p.wait()
except subprocess.CalledProcessError as e:
raise DownloadError(message="Failed to download the video.") from e
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "niconico.py"
version = "2.0.5"
version = "2.0.6"
description = "API wrapper for NicoNico services"
authors = ["Negima1072 <ngm1072@gmail.com>"]
license = "MIT"
Expand Down

0 comments on commit b2feaac

Please sign in to comment.