One Manga Downloader v2.0

Updated

Change log:

  • แก้บั๊กให้ตรวจสอบว่าชื่อไฟล์ต้องเป็น directory เวลาใส่ option -d *
  • แก้บั๊กฟังก์ชันเติมเลขศูนย์หน้า chapter by @crapcode
  • แก้ message บางอัน
  • ฯลฯ

เท่าที่ลองดูคิดว่าน่าจะโอเคแล้ว ออกเป็น stable version เลยละกัน เช่นเคย ถ้าพบบั๊กรบกวนช่วยแจ้งด้วยครับ

สรุปวิธีใช้สำหรับเวอร์ชัน 2.0 ตามนี้ เวลาใส่ option สามารถใส่รวมกันได้หลายๆ อัน เช่น -d -o หรือ -do ก็ให้ผลเหมือนกัน

ดาวน์โหลด chapter ที่ต้องการ

สามารถโหลดทีละ chapter, โหลดเป็นช่วง, หรือโหลดตั้งแต่ chapter ที่กำหนดจนถึง chapter ล่าสุด

onemanga2 -c 350 Naruto
onemanga2 -c 90-97 Full_Metal_Alchemist
onemanga2 -c 200+ Air_Gear

ดาวน์โหลดเฉพาะ chapter ล่าสุด

onemanga2 -l Vagabond

อัพเดตจากที่เคยดาวน์โหลดไว้

สคริปต์จะเช็คไฟล์ .cbr ในเครื่อง แล้วดาวน์โหลด chapter ที่ต่อจาก chapter ปัจจุบัน จนถึง chapter ล่าสุดในเว็บ ถ้าไม่ใส่ option -c หรือ -l สคริปต์จะถือว่าเป็นการอัพเดตเสมอ (ถ้าไม่เคยดาวน์โหลดมาก่อน จะเริ่มจาก chapter แรก)

onemanga2 20th_Century_Boys
onemanga2 -d Video_Girl_AI

ดาวน์โหลดเป็น directory

สามารถใส่ option -d เพื่อดาวน์โหลดมาเก็บใน directory ตามชื่อ manga ได้

onemanga2 -d -c 420 3x3_Eyes
onemanga2 -dl One_Piece
onemanga2 -d Zetman 

ดาวน์โหลดทีละหลายๆ เรื่อง

สามารถใส่ชื่อ manga ได้มากกว่าหนึ่งเรื่องในการดาวน์โหลดแต่ละครั้ง มีประโยชน์มากตอนอัพเดตรายสัปดาห์ ถ้าโหลดโดยใช้ option -d ตลอด ก็ใส่ wildcard แทนชื่อ directory ทั้งหมดไปเลยก็ได้

onemanga2 -dl Naruto Bleach Air_Gear Vagabond Bakuman
onemanga2 -d *

บันทึกชื่อไฟล์ที่ดาวน์โหลดลงใน log file

บางทีเวลาอัพเดตเยอะๆ แล้วอาจจะงงได้ว่าตกลงมันมีไฟล์ไหนบ้างที่เพิ่งดาวน์โหลดมาใหม่ สามารถใส่ option -o เพื่อให้สคริปต์บันทึกวัน-เวลา และชื่อไฟล์ที่ดาวน์โหลดมาไว้ใน onemanga.log เพื่อเปิดดูทีหลังได้

onemanga2 -do *

สำหรับโค้ดก็ตามนี้ครับ จริงๆ น่าเอาไปฝากไว้ใน Google Code หรือ GitHub แต่คิดว่าคงไม่ได้อัพเดตบ่อยๆ เลยช่างมันละกัน :P

#!/bin/bash
#
# usage: onemanga [-dlo] [-c <first chapter>[+|-<last chapter>]] <manga name> [<manga name> ...]
#
 
trap "rm -f *.jpg tmp_*;" 0
 
base_url="http://www.onemanga.com"
base_dir=`pwd`
log="$base_dir/onemanga.log"
 
function calc() {
  echo "scale=2; $*" | bc -q 2>/dev/null | cut -f1 -d.
}
 
function echoes() {
  if [[ $2 -gt 0 ]]; then
    eval "for i in {${3:-1}..$2}; do echo -n '$1'; done"
  fi
}
 
function progressbar() {
  width=20
  current=$1
  total=$2
 
  percent=`calc "$current / $total * 100"`
  stack=`calc "$current / $total * $width"`
  stack=${stack:=0}
  space=`calc "$width - $stack"`
 
  echoes " " ${#percent} 3
  echo -n "$percent% ["
  echoes "#" $stack
  echoes " " $space
  echo "]"
}
 
while getopts ":c:dlo" op; do
  case $op in
    c)
      CHAPTER=1
      CHAPTER_ARG="$OPTARG"
      ;;
    d)
      USE_DIR=1
      ;;
    l)
      LATEST=1
      ;;
    o)
      LOG_FILE=1
      ;;
    \?)
      echo "unknown option: -$OPTARG" >&2
      ERROR=1
      ;;
  esac
done
 
shift $(($OPTIND - 1))
 
if [[ $CHAPTER -eq 1 && $LATEST -eq 1 ]]; then
  echo "invalid option: -c and -l cannot be used at the same time" >&2
  ERROR=1
fi
 
if [[ $ERROR -eq 1 ]]; then
  exit
fi
 
if [[ $CHAPTER = "" && $LATEST = "" ]]; then
  UPDATE=1
fi
 
if [[ $CHAPTER -eq 1 ]]; then
  if [[ `expr index "$CHAPTER_ARG" ++` -gt 0 ]]; then
    first_chapter=${CHAPTER_ARG%+*}
    last_chapter="+"
  elif [[ `expr index "$CHAPTER_ARG" -` -gt 0 ]]; then
    first_chapter=${CHAPTER_ARG%-*}
    last_chapter=${CHAPTER_ARG#*-}
  else
    first_chapter=$CHAPTER_ARG
    last_chapter=$CHAPTER_ARG
  fi
fi
 
for manga_name in "$@"; do
  manga_name=${manga_name%/}
 
  if [[ $USE_DIR -eq 1 ]]; then
    if [[ -f "$base_dir/$manga_name" ]]; then
      echo -e "\n$manga_name [SKIPPED]"
      echo "not a directory"
      continue
    fi
 
    mkdir -p "$base_dir/$manga_name"
    cd "$base_dir/$manga_name"
  fi
 
  display_name=`echo $manga_name | sed "s/_/ /g"`
  word_count=`echo $display_name | wc -w`
  sort_key=$((word_count + 1))
  local_chapter=`ls ${manga_name}_*.cbr 2> /dev/null | sort -r -n -k $sort_key -t_ | head -n1`
  local_chapter=`basename "${local_chapter##*_}" .cbr`
 
  if [[ `echo "$local_chapter == 0" | bc` -eq 0 ]]; then
    local_chapter=`echo $local_chapter | sed "s/^0*//g"`
  fi
 
  echo -ne "\nopening $base_url/$manga_name..."
  wget -qN --no-cache $base_url/$manga_name/
 
  if [[ ! -f "index.html" ]]; then
    echo -e "\b\b\b [ERROR]\nthe url seems to be invalid, or there may be a problem with your internet connection"
    exit
  fi
 
  grep "ch-subject" index.html 2> /dev/null | grep "a href" | cut -f3 -d\/ > tmp_chapters
 
  if [[ ! -s tmp_chapters ]]; then
    echo -e "\b\b\b [ERROR]\ncannot extract chapters info from the url"
    exit
  fi
 
  echo -e "\b\b\b [OK]"
 
  latest_chapter=`head -1 tmp_chapters`
 
  if [[ -n $local_chapter && ! $CHAPTER -eq 1 ]]; then
    echo "local chapter: ${local_chapter} / latest chapter: $latest_chapter"
 
    if [[ $local_chapter == $latest_chapter ]]; then
      echo "no updates found"
      continue
    fi
  fi
 
  if [[ $LATEST -eq 1 ]]; then
    first_chapter=$latest_chapter
    last_chapter=$latest_chapter
  fi
 
  if [[ "$last_chapter" == "+" ]]; then
    last_chapter=$latest_chapter
  fi
 
  if [[ $UPDATE -eq 1 ]]; then
    if [[ $local_chapter == "" ]]; then
      first_chapter=`sort -n tmp_chapters | head -n1`
    else
      index=`sort -n tmp_chapters | grep -nm1 $local_chapter | cut -f1 -d:`
      first_chapter=`sort -n tmp_chapters | tail -n+$((index + 1)) | head -n1`
    fi
 
    last_chapter=$latest_chapter
  fi
 
  if [[ $CHAPTER -eq 1 || -z $local_chapter ]]; then
    echo "from chapter: $first_chapter / to chapter: $last_chapter"
  fi
 
  index=`sort -n tmp_chapters | grep -nm1 $first_chapter | cut -f1 -d:`
  last_index=`sort -n tmp_chapters | grep -nm1 $last_chapter | cut -f1 -d:`
 
  CHAPTERS=`sort -n tmp_chapters | awk 'FNR >= '$index' && FNR <= '$last_index`
 
  for chapter in $CHAPTERS; do
    echo "downloading $display_name chapter $chapter"
    echo -ne "\r\e[0K`progressbar 0 1` (initializing...)"
    page_location=`wget -qO - $base_url/$manga_name/$chapter/ | grep -i "begin reading" | cut -f2 -d\"`
    wget -qO tmp_page $base_url$page_location
    PAGES=`grep -i "option value" tmp_page | grep -i -v "select manga series" | cut -f2 -d\"`
    image_location=`grep -i "manga-page" tmp_page | cut -f4 -d\"`
    image_location=${image_location%/*.jpg}
 
    total=`echo $PAGES | wc -w`
    i=0
 
    for page in $PAGES; do
      let i++
      echo -ne "\r\e[0K`progressbar $i $total` ($i/$total)"
      wget -q "$image_location/$page.jpg"
    done
 
    int_part=${chapter%\.*}
    if [[ `echo "$int_part == 0" | bc` -eq 0 && ${#int_part} -lt 3 ]]; then
      chapter=`echoes "0" ${#int_part} 2`$chapter
    fi
 
    cbr_file_name="${manga_name}_${chapter}.cbr"
 
    echo -ne "\r\e[0K`progressbar $i $total` (packing files...)"
    if zip -q $cbr_file_name *.jpg; then
      rm -f *.jpg tmp_*
      echo -e "\r\e[0K`progressbar $i $total` ($cbr_file_name)"
      [[ $LOG_FILE -eq 1 ]] && echo "[`date +%c`] $cbr_file_name" >> "$log"
    fi
  done
done

9 comments

Anonymous's picture
tuangd (visitor) says:

สุดยอดสคริปต์ครับ เวอร์ชั่นนี้ แจ๋วจริงๆ

Anonymous's picture
Wout Mertens (visitor) says:

Cool, thanks for this script!

I'm sorry, I don't speak Thai :)

There's a few changes I would like to propose:

  1. "expr index" doesn't work on my system (OS X). Instead, why don't you write it like this, using only bash:
if [[ $CHAPTER -eq 1 ]]; then

if [[ "${CHAPTER_ARG%+\*}" != "$CHAPTER_ARG" ]]; then

first_chapter=${CHAPTER_ARG%+*}

last_chapter="+"

elif [[ "${CHAPTER_ARG%-*}" != "$CHAPTER_ARG" ]]; then

first_chapter=${CHAPTER_ARG%-*}

  1. "echo -e "\r\e[0K`..."

didn't work on my terminal. Instead, try this which should work for all terminals:

CLEAREOL="`tput el`"

echo -e "\r$CLEAREOL"

Anyway thanks for your script, it's awesome :)

Wout.

PS: It's really difficult to paste code here...

kong's picture
kong says:

Hi Wout,

Glad you like it! I've modified the code as you suggested and made it available on GitHub. More info here :)

Anonymous's picture
Yumi Nanako (visitor) says:

Hi kong,

I forked your onemanga Downloader on Github and added some options for different archives.

I'm working on a Linux platform so I'm not too sure about Mac OSX and Windows/Cygwin compatability, so hope you don't mind if I broke anything.

http://github.com/yumileroy/onemanga/tree/master

kong's picture
kong says:

Hi Yumi,

Nice options you added there. This would make ppl who prefer other formats than zip really happy.

Thanks for extending onemanga downloader's capability. Now I'm really glad I put it on GitHub :)

Anonymous's picture
Yumi Nanako (visitor) says:

Heh, thanks for the nice script. I was looking for a terminal-based background script for downloading mangas off OneManga.com and I came across many GUI apps and some were broken, but yours was the only script that I came across.

Your script is very useful, since I like to use my ComicRack/Comix to read my mangas.

Currently I'm writing a web php script that execs the onemanga command and lets you specify what you want to download. It's just a simple php prototype script. Heh, just need some tidying before I'm throwing it into Github too.

http://yuminanako.info/omweb/

Feel free to merge my changes from my fork into your project. For more details on merging forks, read here:

http://github.com/guides/keeping-a-git-fork-in-sync-with-the-forked-repo

kong's picture
kong says:

I tried the omweb and it looks very promising!

This would be another choice for people who's not on Linux or doesn't bother to install Cygwin. Plus you can use it anywhere.

Looking forward to see the public release version :)

Anonymous's picture
j_kitar (visitor) says:

ทำอย่างไรให้ใช้กับ proxy ได้คะ

kong's picture
kong says:

อืมมม ยังไม่เคยลองโหลดผ่าน proxy นะครับ ลองใช้คำสั่งนี้ก่อนรันสคริปต์ดูครับ

$ export http_proxy="http://username:password@proxy.example.com:8080"
 

ได้ผลอย่างไรรบกวนแจ้งด้วยนะครับ ถ้าใช้ได้จะได้อัพเดต documentation ต่อไป :)

Post new comment

The content of this field is kept private and will not be shown publicly. If you have a Gravatar account, used to display your avatar.