multimedia/sickchill: Added (Video Library Manager).

Signed-off-by: Willy Sudiarto Raharjo <willysr@slackbuilds.org>
This commit is contained in:
Jeremy Hansen 2023-07-15 17:24:53 +07:00 committed by Willy Sudiarto Raharjo
parent aa3ce12ced
commit c511d2dc98
9 changed files with 493 additions and 0 deletions

View file

@ -0,0 +1,32 @@
sickchill (Less rage, more chill.)
Automatic Video Library Manager for TV Shows. It watches for new
episodes of your favorite shows, and when they are posted it does its
magic.
NOTE: Requires sickchill user and group.
groupadd -g 377 sickchill
useradd -u 377 -g sickchill -d /var/lib/sickchill -s /bin/false sickchill
If you previously had sickrage installed, please change the user and
group with the following:
groupmod -n sickchill sickrage
usermod -l sickchill -g sickchill -d /var/lib/sickchill sickrage
To have this start up with Slackware, please add the following to your
/etc/rc.d/rc.local:
# Start sickrage
if [ -x /etc/rc.d/rc.sickrage ]; then
/etc/rc.d/rc.sickrage start
fi
If you want it to shut down properly when Slackware restarts or shuts
down, please add the following to your /etc/rc.d/rc.local_shutdown
(it may need to be created):
# Stop sickrage
if [ -x /etc/rc.d/rc.sickrage ]; then
/etc/rc.d/rc.sickrage stop
fi

View file

@ -0,0 +1,3 @@
[General]
log_dir = /var/log/sickchill
version_notify = 0

View file

@ -0,0 +1,27 @@
config() {
NEW="$1"
OLD="$(dirname $NEW)/$(basename $NEW .new)"
# If there's no config file by that name, mv it over:
if [ ! -r $OLD ]; then
mv $NEW $OLD
elif [ "$(cat $OLD | md5sum)" = "$(cat $NEW | md5sum)" ]; then
# toss the redundant copy
rm $NEW
fi
# Otherwise, we leave the .new copy for the admin to consider...
}
preserve_perms() {
NEW="$1"
OLD="$(dirname $NEW)/$(basename $NEW .new)"
if [ -e $OLD ]; then
cp -a $OLD ${NEW}.incoming
cat $NEW > ${NEW}.incoming
mv ${NEW}.incoming $NEW
fi
config $NEW
}
preserve_perms etc/rc.d/rc.sickchill.new
config etc/sickchill.conf.new
config var/lib/sickchill/config.ini.new

View file

@ -0,0 +1,118 @@
#!/bin/bash
# Start/stop/restart sickchill.
# rc.sickrage created by Jeremy Hansen for Slackware in 2016
# rc.sickchill was updated by Jeremy Hansen for Slackware in 2023
# Set program name in case you want to run sick{beard|rage|gear|etc}
PROG=${PROG:-sickchill}
# Source SickRage configuration
if [ -f /etc/"$PROG".conf ]; then
. /etc/"$PROG".conf
fi
# Ensure all required variables are set in conf file
# Edit conf file in /etc/sickchill.conf for any changes
for var in USERNAME HOMEDIR DATADIR PIDFILE PORT; do
if [ -z "${!var}" ]; then
echo "/etc/$PROG.conf is missing some or all required variables ($var)."
echo "Please check the file and try again."
exit 1
fi
done
# Check if the program is running and pid file exists
check() {
if pgrep "$PROG" > /dev/null; then
if [ -e "$PIDFILE" ] && ! pgrep -F "$PIDFILE" > /dev/null; then
STATUS=broken
echo "WARNING: $PROG is running, but its PID does not match the one in $PIDFILE."
elif [ ! -e "$PIDFILE" ]; then
STATUS=broken
echo "WARNING: $PROG is running, but $PIDFILE does not exist."
echo "Maybe you ran $PROG from the commandline rather than rc.sickchill?"
else
STATUS=running
fi
else
if [ -e "$PIDFILE" ]; then
STATUS=broken
echo "WARNING: $PROG is not running but $PIDFILE exists."
else
STATUS=stopped
fi
fi
}
status() {
if [ $STATUS == "running" ]; then
echo "$PROG currently running."
elif [ $STATUS == "stopped" ]; then
echo "$PROG not running."
elif [ $STATUS == "broken" ]; then
echo "Please fix the issue before attempting to run $(basename "$0") again."
else
echo "Status unknown."
fi
}
start() {
if [ $STATUS == "running" ]; then
echo "$PROG already running or not shut down properly."
else
echo -n "Starting $PROG: "
if su "$USERNAME" -s /bin/sh -c "/usr/bin/sickchill --daemon --pidfile=${PIDFILE} --datadir=${DATADIR} --port=${PORT} &> /dev/null"; then
echo "Startup Successful"
else
echo "Startup Failed. Please try running the following to see the errors."
echo "su $USERNAME -s /bin/sh -c \"/usr/bin/sickchill --daemon --pidfile=${PIDFILE} --datadir=${DATADIR} --port=${PORT}\""
fi
fi
}
stop() {
if [ $STATUS == "stopped" ]; then
echo "$PROG doesn't seem to be running. Please try running"
echo "$0 start"
elif [ $STATUS == "broken" ]; then
echo "Cannot stop. Please correct issue and try again."
else
if [ "$EUID" -ne 0 ];then
echo "Please run as root"
exit 1
fi
PID=$(cat "$PIDFILE")
echo -n $"Shutting down $PROG: "
if ! curl -s http://localhost:"$PORT"/home/shutdown/?pid="$PID" | grep -q "shutting down"; then
echo "Normal Shutdown Failed - Attempting to kill the process."
sleep 7
kill -9 "$PID"
else
echo "Shutdown Successful"
fi
fi
}
case "$1" in
start)
check
start
;;
stop)
check
stop
;;
restart)
check
stop
start
;;
status)
check
status
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
esac

View file

@ -0,0 +1,111 @@
#!/bin/bash
# Slackware build script for sickchill
# Copyright 2023 Jeremy Hansen jebrhansen+SBo@gmail.com
# All rights reserved.
#
# Redistribution and use of this script, with or without modification, is
# permitted provided that the following conditions are met:
#
# 1. Redistributions of this script must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
cd $(dirname $0) ; CWD=$(pwd)
PRGNAM=sickchill
VERSION=${VERSION:-2023.6.27}
BUILD=${BUILD:-1}
TAG=${TAG:-_SBo}
PKGTYPE=${PKGTYPE:-tgz}
if [ -z "$ARCH" ]; then
case "$( uname -m )" in
i?86) ARCH=i586 ;;
arm*) ARCH=arm ;;
*) ARCH=$( uname -m ) ;;
esac
fi
SICKUSER=${SICKUSER:-sickchill}
SICKGROUP=${SICKGROUP:-sickchill}
# The user and group accounts need to be created manually.
# For slackbuilds.org, assigned sickchill uid/gid are 377/377
# See http://slackbuilds.org/uid_gid.txt
if ! grep ^$SICKGROUP: /etc/group 2>&1 > /dev/null; then
echo " You must have a \"$SICKGROUP\" group to run this script."
echo " # groupadd -g 377 $SICKGROUP"
echo " If you previously had sickrage installed, change the group using"
echo " # groupmod -n sickchill sickrage"
exit 1
elif ! grep ^$SICKUSER: /etc/passwd 2>&1 > /dev/null; then
echo " You must have a \"$SICKUSER\" user to run this script."
echo " # useradd -u 377 -g $SICKGROUP -d /var/lib/sickchill -s /bin/false $SICKUSER"
echo " If you previously had sickrage installed, change the user using"
echo " # usermod -l sickchill -g sickchill -d /var/lib/sickchill sickrage"
exit 1
fi
if [ ! -z "${PRINT_PACKAGE_NAME}" ]; then
echo "$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE"
exit 0
fi
TMP=${TMP:-/tmp/SBo}
PKG=$TMP/package-$PRGNAM
OUTPUT=${OUTPUT:-/tmp}
set -e
rm -rf $PKG
mkdir -p $TMP $PKG $OUTPUT
cd $TMP
rm -rf $PRGNAM-$VERSION
tar xvf $CWD/$PRGNAM-$VERSION.tar.gz
cd $PRGNAM-$VERSION
chown -R root:root .
find -L . \
\( -perm 777 -o -perm 775 -o -perm 750 -o -perm 711 -o -perm 555 \
-o -perm 511 \) -exec chmod 755 {} \; -o \
\( -perm 666 -o -perm 664 -o -perm 640 -o -perm 600 -o -perm 444 \
-o -perm 440 -o -perm 400 \) -exec chmod 644 {} \;
# Revert changes that require SQLAlchmey > 2.0 until SBo catches up
patch -p1 < $CWD/use-older-SQLAlchemy.patch
python3 -m build --wheel --no-isolation
python3 -m installer --destdir=$PKG dist/*.whl
find $PKG -print0 | xargs -0 file | grep -e "executable" -e "shared object" | grep ELF \
| cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null || true
mkdir -p $PKG/usr/doc/$PRGNAM-$VERSION
cp -a \
COPYING.txt LICENSE.md README.md SECURITY.md \
$PKG/usr/doc/$PRGNAM-$VERSION
cat $CWD/$PRGNAM.SlackBuild > $PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.SlackBuild
mkdir -p $PKG/etc/rc.d/
install -m 0644 $CWD/rc.sickchill $PKG/etc/rc.d/rc.sickchill.new
install -m 0644 $CWD/sickchill.conf $PKG/etc/sickchill.conf.new
install -dm 0755 --owner=$SICKUSER $PKG/var/lib/sickchill/
install -m 0644 --owner=$SICKUSER $CWD/config.ini $PKG/var/lib/sickchill/config.ini.new
install -dm 0755 --owner=$SICKUSER $PKG/var/log/sickchill/
mkdir -p $PKG/install
cat $CWD/slack-desc > $PKG/install/slack-desc
cat $CWD/doinst.sh > $PKG/install/doinst.sh
cd $PKG
/sbin/makepkg -l y -c n $OUTPUT/$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE

View file

@ -0,0 +1,6 @@
USERNAME=sickchill
HOMEDIR=/usr/share/sickchill
DATADIR=/var/lib/sickchill
PIDFILE=${DATADIR}/sickchill.pid
PORT=8081
LOGDIR=/var/log/sickchill

View file

@ -0,0 +1,10 @@
PRGNAM="sickchill"
VERSION="2023.6.27"
HOMEPAGE="https://sickchill.github.io/"
DOWNLOAD="https://github.com/SickChill/sickchill/archive/refs/tags/2023.6.27/sickchill-2023.6.27.tar.gz"
MD5SUM="e38394951cead23e349470c48706fa7e"
DOWNLOAD_x86_64=""
MD5SUM_x86_64=""
REQUIRES="python3-poetry-core python3-PyGithub rarfile python3-ifaddr python3-cacheyou python3-tornado Unidecode python-gntp python3-kodipydent python3-cinemagoer python3-validators python3-bencode python-jsonrpclib python3-markdown2 python3-guessit subliminal twitter requests-oauthlib configobj imagesize python3-tvdbsimple python3-fanart python3-tmdbsimple python3-slugify send2trash pyOpenSSL pymediainfo python3-putio.py python3-pynma python3-deluge-client python3-qbittorrent-api python3-new-rtorrent"
MAINTAINER="Jeremy Hansen"
EMAIL="jebrhansen+SBo@gmail.com"

View file

@ -0,0 +1,19 @@
# HOW TO EDIT THIS FILE:
# The "handy ruler" below makes it easier to edit a package description.
# Line up the first '|' above the ':' following the base package name, and
# the '|' on the right side marks the last column you can put a character in.
# You must make exactly 11 lines for the formatting to be correct. It's also
# customary to leave one space after the ':' except on otherwise blank lines.
|-----handy-ruler------------------------------------------------------|
sickchill: sickchill (Less rage, more chill.)
sickchill:
sickchill: Automatic Video Library Manager for TV Shows. It watches for new
sickchill: episodes of your favorite shows, and when they are posted it does
sickchill: its magic.
sickchill:
sickchill: HOMEPAGE: https://sickchill.github.io/
sickchill:
sickchill:
sickchill:
sickchill:

View file

@ -0,0 +1,167 @@
diff --git a/sickchill/oldbeard/databases/movie.py b/sickchill/oldbeard/databases/movie.py
index 3598dcc..52000a3 100644
--- a/sickchill/oldbeard/databases/movie.py
+++ b/sickchill/oldbeard/databases/movie.py
@@ -4,45 +4,43 @@ from typing import List
import guessit
from slugify import slugify
-from sqlalchemy import ForeignKey, JSON
+from sqlalchemy import Boolean, Column, Date, DateTime, ForeignKey, Integer, Interval, JSON, SmallInteger, String
from sqlalchemy.event import listen
from sqlalchemy.ext.declarative import declarative_base
-from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship, sessionmaker
+from sqlalchemy.orm import relationship, sessionmaker
logger = logging.getLogger("sickchill.movie")
-
-class Base(DeclarativeBase):
- """Declarative Base Class"""
-
+Base = declarative_base()
Session = sessionmaker()
class Movie(Base):
__tablename__ = "movie"
- pk: Mapped[int] = mapped_column(primary_key=True)
- name: Mapped[str]
- date: Mapped[datetime.date]
- year: Mapped[int]
- status: Mapped[int]
- paused: Mapped[bool] = mapped_column(default=False)
- location: Mapped[str]
- start: Mapped[datetime.timedelta] = mapped_column(default=datetime.timedelta(days=-7))
- interval: Mapped[datetime.timedelta] = mapped_column(default=datetime.timedelta(days=1))
- added: Mapped[datetime.datetime] = mapped_column(default=datetime.datetime.now)
- updated: Mapped[datetime.datetime] = mapped_column(onupdate=datetime.datetime.now)
- completed: Mapped[datetime.datetime]
- searched: Mapped[datetime.datetime]
- slug: Mapped[str]
-
- language: Mapped[str]
-
- result_pk: Mapped[int] = mapped_column(ForeignKey("result.pk"))
- results: Mapped[List["Result"]] = relationship(backref="movie")
-
- images: Mapped[List["Images"]] = relationship(backref="movie")
- indexer_data: Mapped[List["IndexerData"]] = relationship(backref="movie")
+
+ pk = Column(Integer, primary_key=True)
+ name = Column(String)
+ date = Column(Date)
+ year = Column(SmallInteger)
+ status = Column(Integer)
+ paused = Column(Boolean, default=False)
+ location = Column(String)
+ start = Column(Interval, default=datetime.timedelta(days=-7))
+ interval = Column(Interval, default=datetime.timedelta(days=1))
+ added = Column(DateTime, default=datetime.datetime.now)
+ updated = Column(DateTime, onupdate=datetime.datetime.now)
+ completed = Column(DateTime)
+ searched = Column(DateTime)
+ slug = Column(String)
+
+ language = Column(String)
+
+ result_pk = Column(Integer, ForeignKey("result.pk"))
+ results: list = relationship("Result", backref="movie")
+
+ images: list = relationship("Images", backref="movie")
+ indexer_data: list = relationship("IndexerData", backref="movie")
def __init__(self, name: str, year: int):
self.name = name
@@ -134,21 +132,21 @@ listen(Movie.name, "set", Movie.slugify, retval=False)
class Result(Base):
__tablename__ = "result"
- pk: Mapped[int] = mapped_column(primary_key=True)
- name: Mapped[str]
- title: Mapped[str]
- url: Mapped[str]
- size: Mapped[int]
- year: Mapped[int]
- provider: Mapped[str]
- seeders: Mapped[int]
- leechers: Mapped[int]
- info_hash: Mapped[str]
- group: Mapped[str]
- kind: Mapped[str]
- guess = mapped_column(JSON)
- found: Mapped[datetime.datetime] = mapped_column(default=datetime.datetime.now)
- updated: Mapped[datetime.datetime] = mapped_column(onupdate=datetime.datetime.now)
+ pk = Column(Integer, primary_key=True)
+ name = Column(String)
+ title = Column(String)
+ url = Column(String)
+ size = Column(Integer)
+ year = Column(SmallInteger)
+ provider = Column(String)
+ seeders = Column(Integer)
+ leechers = Column(Integer)
+ info_hash = Column(String)
+ group = Column(String)
+ type = Column(String)
+ guess = Column(JSON)
+ found = Column(DateTime, default=datetime.datetime.now)
+ updated = Column(DateTime, onupdate=datetime.datetime.now)
session = Session()
@@ -172,7 +170,7 @@ class Result(Base):
self.leechers = result["leechers"]
self.size = result["size"]
self.year = guess["year"] or movie.year
- self.kind = provider.provider_type
+ self.type = provider.provider_type
self.provider = provider.get_id()
@@ -187,12 +185,12 @@ class Result(Base):
class Images(Base):
__tablename__ = "images"
- url: Mapped[str] = mapped_column(primary_key=True)
- path: Mapped[str]
- site: Mapped[str]
- style: Mapped[int]
+ url = Column(String, primary_key=True)
+ path = Column(String)
+ site = Column(String)
+ style = Column(Integer)
- movie_pk: Mapped[int] = mapped_column(ForeignKey("movie.pk"))
+ movie_pk = Column(Integer, ForeignKey("movie.pk"))
def __init__(self, site: str, movie_pk: int, url: str, path: str, style: int):
self.url = url
@@ -204,13 +202,13 @@ class Images(Base):
class IndexerData(Base):
__tablename__ = "indexer_data"
- pk: Mapped[str] = mapped_column(primary_key=True)
- site: Mapped[str]
- data = mapped_column(JSON)
+ pk = Column(String, primary_key=True)
+ site = Column(String)
+ data = Column(JSON)
- movie_pk: Mapped[int] = mapped_column(ForeignKey("movie.pk"))
+ movie_pk = Column(Integer, ForeignKey("movie.pk"))
- genres: Mapped[List["Genres"]] = relationship(backref="indexer_data")
+ genres: list = relationship("Genres", backref="indexer_data")
def __repr__(self):
return f"[{self.__tablename__.replace('_', ' ').title()}] {self.site}: {self.pk} - {self.movie.name}"
@@ -218,5 +216,5 @@ class IndexerData(Base):
class Genres(Base):
__tablename__ = "genres"
- pk: Mapped[str] = mapped_column(primary_key=True)
- indexer_data_pk: Mapped[int] = mapped_column(ForeignKey("indexer_data.pk"))
+ pk = Column(String, primary_key=True)
+ indexer_data_pk = Column(Integer, ForeignKey("indexer_data.pk"))