Skip to content

Add docker. Other light fixes for paths #24

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Dec 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Extras That Shouldn't Be Here
.gitignore
.dockerignore
docker-compose.yml
Dockerfile

# Frontend
.DS_Store
/build
/.svelte-kit
/package
.env
.env.*
!.env.example

# Backend
logs/
settings.json
__pycache__
*.log
data
test*

# Jupyter Notebooks
.ipynb_checkpoints

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

### VisualStudioCode ###
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets

# Local History for Visual Studio Code
.history/

# Built Visual Studio Code Extensions
*.vsix

### VisualStudioCode Patch ###
# Ignore all local history of files
.history
.ionide
31 changes: 31 additions & 0 deletions .github/workflows/docker-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Docker Build and Push

on:
push:
branches:
- main

jobs:
build-and-push:
runs-on: ubuntu-latest

steps:
- name: Check out the repo
uses: actions/checkout@v2

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1

- name: Log in to Docker Hub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}

- name: Build and push Docker image
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile
push: true
tags: spoked/iceberg:latest
25 changes: 25 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
FROM alpine:3.19

LABEL org.label-schema.name="Iceberg" \
org.label-schema.description="Iceberg Debrid Downloader" \
org.label-schema.url="https://github.com/dreulavelle/iceberg"

RUN apk --update add python3 py3-pip nodejs npm bash && \
rm -rf /var/cache/apk/*

RUN npm install -g pnpm

WORKDIR /iceberg
COPY . /iceberg/

RUN python3 -m venv /venv && \
source /venv/bin/activate && \
pip3 install --no-cache-dir -r /iceberg/requirements.txt

RUN cd /iceberg/frontend && \
pnpm install && \
pnpm run build

EXPOSE 4173

CMD cd /iceberg/frontend && pnpm run preview --host & cd /iceberg/backend && source /venv/bin/activate && exec python main.py
81 changes: 62 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,83 @@

The idea behind this was to make a simple and functional rewrite of plex debrid that seemed to get a bit clustered.

Rewrite of plex_debrid project, limited functionality:
- Services include: plex, mdblist, torrentio and realdebrid
Rewrite of [plex_debrid](https://github.com/itsToggle/plex_debrid) project.

Currently:
- Services include: Plex, Mdblist, Torrentio and Real Debrid

TODO:
- Implement uncached download in real-rebrid, dont know if we need this, movies seem to work ok...
- Implement updating quality of fetched items if below something
- Add frontend, ongoing... (adding api endpoints as we go along)

Check out out [Project Board](https://github.com/users/dreulavelle/projects/2) to stay informed!

COMPLETED:
- ~~Update plex libraries for changes, ongoing... ~~; (functional but we need to be more specific when to update)
- ~~Real-debrid should download only one file per stream, lets avoid collections~~
- ~~Modify scraping logic to try scaping once a day if not found?~~
- ~~Add overseerr support, mostly done~~; still need to mark items as available?
- ~~Add support for shows, ongoing...~~ (Functionalish, needs work...)
- ~~Modify scraping logic to try scaping once a day if not found?~~
- ~~Store data with pickle~~
- ~~Improve logging...~~
- ~~Update plex libraries for changes, ongoing... ~~; (functional but we need to be more specific when to update)
- Add frontend, ongoing... (adding api endpoints as we go along)
- ~~Add support for shows, ongoing...~~ (Functionalish, needs work...)
- Implement uncached download in real-rebrid, dont know if we need this, movies seem to work ok...
- Implement updating quality of fetched items if below something
- And more..

Please add features and mention issues over on our [Issue Tracker](https://github.com/dreulavelle/iceberg/issues)!

## Running the project
We are constantly adding features and improvements as we go along and squashing bugs as they arise.

```
pip install -r requirements.txt
```
Enjoy!

## Docker Compose

```yml
version: '3.8'

services:
iceberg:
image: iceberg:latest
container_name: Iceberg
restart: unless-stopped
ports:
- "4173:4173"
volumes:
- ./data:/iceberg/data
# healthcheck:
# test: ["CMD", "curl", "-f", "http://localhost:8080/"]
# interval: 1m30s
# timeout: 10s
# retries: 1
```

> [!WARNING]
> You must have a standard settings.json file already in place before bind mounting it!
> An empty settings.json file, or no file at all, will cause issues!

You can get a copy of the default settings [here](https://raw.githubusercontent.com/dreulavelle/iceberg/main/backend/utils/default_settings.json)

After copying over the settings file (on a fresh install) you can bind mount it like the compose above.

## Running outside of Docker

```sh
pip install -r requirements.txt
python3 backend/main.py
cd frontend && npm install && npm run dev
```

```
cd frontend
## Development

npm install
npm run dev
First terminal:

# OR
```sh
git clone https://github.com/dreulavelle/iceberg.git
cd frontend && npm install && npm run dev
```

Seperate terminal:

pnpm install
pnpm run dev
```sh
python backend/main.py
```
```
2 changes: 1 addition & 1 deletion backend/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def lifespan(app: FastAPI):

if __name__ == "__main__":
try:
uvicorn.run("main:app", host="localhost", port=8080, reload=False)
uvicorn.run("main:app", host="0.0.0.0", port=8080, reload=False)
except KeyboardInterrupt:
print("Exiting...")
sys.exit(0)
6 changes: 6 additions & 0 deletions backend/program/program.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import inspect
import os
import sys
from typing import Optional
from pydantic import BaseModel, HttpUrl, Field
from program.symlink import Symlinker
from utils.logger import logger, get_data_path
Expand All @@ -16,6 +17,7 @@ class PlexConfig(BaseModel):
user: str
token: str
address: HttpUrl
watchlist: Optional[HttpUrl] = None

class MdblistConfig(BaseModel):
lists: list[str] = Field(default_factory=list)
Expand Down Expand Up @@ -93,6 +95,10 @@ def _validate_modules(self):
return False

def __import_modules(self, folder_path: str) -> list[object]:
if os.path.exists('/iceberg'):
folder_path = os.path.join('/iceberg', folder_path)
else:
folder_path = folder_path
file_list = [
f[:-3]
for f in os.listdir(folder_path)
Expand Down
6 changes: 3 additions & 3 deletions backend/program/updaters/trakt.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def __init__(self):

def create_items(self, imdb_ids):
"""Update media items to state where they can start downloading"""
self.trakt_data.load("backend/data/trakt_data.pkl")
self.trakt_data.load("data/trakt_data.pkl")
new_items = MediaItemContainer()
get_items = MediaItemContainer()
for imdb_id in imdb_ids:
Expand All @@ -38,7 +38,7 @@ def create_items(self, imdb_ids):
for added_item in added_items:
logger.debug("Added %s", added_item.title)
self.trakt_data.extend(added_items)
self.trakt_data.save("backend/data/trakt_data.pkl")
self.trakt_data.save("data/trakt_data.pkl")

return get_items

Expand Down Expand Up @@ -125,4 +125,4 @@ def create_item_from_imdb_id(imdb_id: str):
data = response.data[0].show
if data:
return _map_item_from_data(data, media_type)
return None
return None
15 changes: 8 additions & 7 deletions backend/utils/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,27 @@ class SettingsManager:
"""Class that handles settings"""

def __init__(self):
self.filename = "settings.json"
self.filename = "data/settings.json"
self.config_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir))
self.settings_file = os.path.join(self.config_dir, self.filename)
self.settings = {}
self.load()

def load(self):
"""Load settings from file"""
if not os.path.exists(os.path.join(self.config_dir, self.filename)):
shutil.copy(os.path.join(os.path.dirname(__file__), "default_settings.json"), os.path.join(self.config_dir, self.filename))
if not os.path.exists(self.settings_file):
default_settings_path = os.path.join(os.path.dirname(__file__), "default_settings.json")
shutil.copy(default_settings_path, self.settings_file)
logger.debug("Settings file not found, using default settings")
with open(self.filename, "r", encoding="utf-8") as file:
with open(self.settings_file, "r", encoding="utf-8") as file:
self.settings = json.loads(file.read())
logger.debug("Settings loaded from %s", self.filename)
logger.debug("Settings loaded from %s", self.settings_file)

def save(self):
"""Save settings to file"""
with open(self.filename, "w", encoding="utf-8") as file:
with open(self.settings_file, "w", encoding="utf-8") as file:
json.dump(self.settings, file, indent=4)
logger.debug("Settings saved to %s", self.filename)
logger.debug("Settings saved to %s", self.settings_file)

def get(self, key):
"""Get setting with key"""
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ pathos
pydantic
fastapi
uvicorn[standard]
parse-torrent-file
parse-torrent-title