diff --git a/README.md b/README.md
index 06b65fa..79626da 100644
--- a/README.md
+++ b/README.md
@@ -15,5 +15,6 @@ There is a simple web UI to add the doujinshi IDs to the queue.
 - [ ] Add file name normalizer (for kavita)
 - [ ] Add file mover (organizer)
 - [ ] Add config file
-- [ ] Add Database integration (sqlite from nhentail cli tool)
+- [x] Add Database integration (sqlite from nhentail cli tool)
 - [ ] Add Dockerfile
+- [ ] Better error handeling (Show in UI)
diff --git a/src/main.py b/src/main.py
deleted file mode 100644
index 4ec3327..0000000
--- a/src/main.py
+++ /dev/null
@@ -1,307 +0,0 @@
-from nicegui import ui, app
-import time
-import subprocess
-import os
-import threading
-from collections import defaultdict
-
-ui.dark_mode().enable()
-
-# Configuration
-DOWNLOAD_DIR = os.path.expanduser("~/Downloads/doujinshi")
-OUTPUT_FORMAT = "[%i]%s"  # Default format for folder naming
-COOKIE = ""  # For bypassing Cloudflare captcha
-USER_AGENT = ""  # For bypassing Cloudflare captcha
-HTML_VIEWER = False  # Generate HTML viewer
-GENERATE_CBZ = True  # Generate Comic Book Archive
-GENERATE_PDF = False  # Generate PDF file
-THREAD_COUNT = 5  # Thread count for downloading
-TIMEOUT = 30  # Timeout in seconds
-RETRY_COUNT = 3  # Retry times when download fails
-
-# Global dictionary to track download statuses
-download_statuses = {}
-
-def add_nhentai_id():
-    id_value = id_input.value
-    if not id_value:
-        ui.notify('Please enter an ID', color='warning')
-        return
-
-    # Clear the input field after submission
-    id_input.value = ''
-
-    # Show notification
-    ui.notify(f'Adding nhentai ID: {id_value}')
-
-    # Create a new history item
-    with history_container:
-        item_row = ui.row().classes('w-full items-center')
-        with item_row:
-            status = ui.icon('circle').classes('text-yellow-500')  # Initial "processing" status
-            ui.label(f'ID: {id_value}').classes('text-lg ml-2')
-            timestamp = ui.label(f'Added: {time.strftime("%H:%M:%S")}').classes('text-sm text-gray-500 ml-auto')
-
-            # Add buttons for actions
-            download_btn = ui.button('Download',
-                                    on_click=lambda: start_download(id_value, status),
-                                    color='primary').classes('ml-2').props('size=sm')
-
-def update_status(status_icon, id_value, success=True):
-    if success:
-        status_icon.name = 'check_circle'
-        status_icon.classes('text-green-500', remove='text-yellow-500 text-red-500 text-blue-500')
-    else:
-        status_icon.name = 'error'
-        status_icon.classes('text-red-500', remove='text-yellow-500 text-green-500 text-blue-500')
-        ui.notify(f'ID {id_value} marked as failed', color='negative')
-
-def download_doujinshi(id_value, status_icon):
-    # This function runs in a background thread
-    global download_statuses
-
-    try:
-        # Try to check if nhentai CLI is installed
-        try:
-            subprocess.run(["nhentai", "--help"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True)
-        except (subprocess.SubprocessError, FileNotFoundError):
-            download_statuses[id_value] = {
-                'status': 'error',
-                'message': 'nhentai CLI tool is not installed'
-            }
-            return
-
-        # Create download directory if it doesn't exist
-        os.makedirs(DOWNLOAD_DIR, exist_ok=True)
-
-        # Build command with all options
-        cmd = ["nhentai"]
-
-        # Add the ID
-        cmd.extend(["--id", str(id_value)])
-
-        # Add output directory
-        cmd.extend(["--output", DOWNLOAD_DIR])
-
-        # Add format option
-        cmd.extend(["--format", OUTPUT_FORMAT])
-
-        # Add thread count
-        if THREAD_COUNT > 0:
-            cmd.extend(["--threads", str(THREAD_COUNT)])
-
-        # Add timeout
-        if TIMEOUT > 0:
-            cmd.extend(["--timeout", str(TIMEOUT)])
-
-        # Add retry count
-        if RETRY_COUNT > 0:
-            cmd.extend(["--retry", str(RETRY_COUNT)])
-
-        # Add exit-on-fail option to prevent incomplete downloads
-        cmd.append("--exit-on-fail")
-
-        # Add HTML viewer option
-        if HTML_VIEWER:
-            cmd.append("--html")
-        else:
-            cmd.append("--no-html")
-
-        # Generate CBZ if selected
-        if GENERATE_CBZ:
-            cmd.append("--cbz")
-
-        # Generate PDF if selected
-        if GENERATE_PDF:
-            cmd.append("--pdf")
-
-        # Add cookie if provided
-        if COOKIE:
-            cmd.extend(["--cookie", COOKIE])
-
-        # Add user agent if provided
-        if USER_AGENT:
-            cmd.extend(["--useragent", USER_AGENT])
-
-        # Save download history
-        cmd.append("--save-download-history")
-
-        # For debugging: print the command (excluding sensitive info)
-        debug_cmd = list(cmd)
-        if COOKIE:
-            cookie_index = debug_cmd.index("--cookie")
-            if len(debug_cmd) > cookie_index + 1:
-                debug_cmd[cookie_index + 1] = "***COOKIE***"
-
-        if USER_AGENT:
-            ua_index = debug_cmd.index("--useragent")
-            if len(debug_cmd) > ua_index + 1:
-                debug_cmd[ua_index + 1] = "***USER-AGENT***"
-
-        print(f"Executing: {' '.join(debug_cmd)}")
-
-        process = subprocess.Popen(
-            cmd,
-            stdout=subprocess.PIPE,
-            stderr=subprocess.PIPE,
-            text=True
-        )
-        stdout, stderr = process.communicate()
-
-        # Use the global dict to track status
-        if process.returncode == 0:
-            # Success
-            download_statuses[id_value] = {
-                'status': 'success',
-                'message': 'Download completed'
-            }
-            print(f"Download successful for ID {id_value}")
-            print(f"STDOUT: {stdout}")
-        else:
-            # Error
-            download_statuses[id_value] = {
-                'status': 'error',
-                'message': f'Download failed: {stderr}'
-            }
-            print(f"Download failed for ID {id_value}")
-            print(f"STDERR: {stderr}")
-    except Exception as e:
-        # Error handling
-        download_statuses[id_value] = {
-            'status': 'error',
-            'message': f'Error: {str(e)}'
-        }
-        print(f"Exception during download for ID {id_value}: {str(e)}")
-
-def start_download(id_value, status_icon):
-    # Update status to "downloading"
-    status_icon.name = 'downloading'
-    status_icon.classes('text-blue-500', remove='text-yellow-500 text-green-500 text-red-500')
-    ui.notify(f'Starting download for ID: {id_value}', color='info')
-
-    # Initialize download status
-    global download_statuses
-    download_statuses[id_value] = {'status': 'downloading'}
-
-    # Start download in a background thread
-    threading.Thread(target=download_doujinshi, args=(id_value, status_icon), daemon=True).start()
-
-    # Set up a periodic task to check for download completion
-    check_download_status(id_value, status_icon)
-
-def check_download_status(id_value, status_icon):
-    """Check if the download has completed and update the UI accordingly"""
-    global download_statuses
-
-    if id_value in download_statuses:
-        result = download_statuses[id_value]
-        if result.get('status') == 'success':
-            ui.notify(f'Download completed for ID: {id_value}', color='positive')
-            update_status(status_icon, id_value, True)
-            # Remove from tracking to avoid duplicate notifications
-            del download_statuses[id_value]
-        elif result.get('status') == 'error':
-            ui.notify(f'Download failed for ID {id_value}: {result.get("message", "Unknown error")}', color='negative')
-            update_status(status_icon, id_value, False)
-            # Remove from tracking to avoid duplicate notifications
-            del download_statuses[id_value]
-        else:
-            # Still processing, check again in a second
-            ui.timer(1.0, lambda: check_download_status(id_value, status_icon), once=True)
-    else:
-        # No result yet, check again in a second
-        ui.timer(1.0, lambda: check_download_status(id_value, status_icon), once=True)
-
-# Add advanced settings dialog
-def show_settings():
-    with ui.dialog() as dialog, ui.card().classes('w-96'):
-        ui.label('Download Settings').classes('text-xl font-bold')
-
-        global DOWNLOAD_DIR, OUTPUT_FORMAT, COOKIE, USER_AGENT, HTML_VIEWER, GENERATE_CBZ, GENERATE_PDF, THREAD_COUNT, TIMEOUT, RETRY_COUNT
-
-        # Basic Settings
-        ui.label('Basic Settings').classes('text-lg font-semibold mt-4')
-        download_dir_input = ui.input('Download Directory', value=DOWNLOAD_DIR).classes('w-full')
-        output_format_input = ui.input('Output Format', value=OUTPUT_FORMAT,
-                                     placeholder='e.g. [%i]%s').classes('w-full')
-        ui.label('Supported: %i (ID), %s (subtitle), %t (title), %a (authors), %g (groups), %p (pretty name)').classes('text-xs text-gray-500')
-
-        # Advanced Settings
-        ui.label('Advanced Settings').classes('text-lg font-semibold mt-4')
-        thread_count_input = ui.number('Thread Count', value=THREAD_COUNT, min=1, max=20)
-        timeout_input = ui.number('Timeout (seconds)', value=TIMEOUT, min=5, max=120)
-        retry_count_input = ui.number('Retry Count', value=RETRY_COUNT, min=0, max=10)
-
-        # Output Options
-        ui.label('Output Options').classes('text-lg font-semibold mt-4')
-        html_viewer_toggle = ui.switch('Generate HTML Viewer', value=HTML_VIEWER)
-        cbz_toggle = ui.switch('Generate CBZ File', value=GENERATE_CBZ)
-        pdf_toggle = ui.switch('Generate PDF File', value=GENERATE_PDF)
-
-        # Authentication (for bypassing Cloudflare)
-        ui.label('Authentication (to bypass Cloudflare)').classes('text-lg font-semibold mt-4')
-        cookie_input = ui.input('Cookie', value=COOKIE,
-                              placeholder='csrftoken=TOKEN; sessionid=ID; cf_clearance=CLOUDFLARE').classes('w-full')
-        useragent_input = ui.input('User Agent', value=USER_AGENT,
-                                  placeholder='Mozilla/5.0 ...').classes('w-full')
-
-        with ui.row():
-            ui.button('Cancel', on_click=dialog.close).props('outline')
-            ui.button('Save', on_click=lambda: save_settings(
-                download_dir_input.value,
-                output_format_input.value,
-                cookie_input.value,
-                useragent_input.value,
-                html_viewer_toggle.value,
-                cbz_toggle.value,
-                pdf_toggle.value,
-                thread_count_input.value,
-                timeout_input.value,
-                retry_count_input.value,
-                dialog
-            ))
-    dialog.open()
-
-def save_settings(download_dir, output_format, cookie, useragent,
-                html_viewer, generate_cbz, generate_pdf, thread_count, timeout, retry_count, dialog):
-    global DOWNLOAD_DIR, OUTPUT_FORMAT, COOKIE, USER_AGENT, HTML_VIEWER, GENERATE_CBZ, GENERATE_PDF, THREAD_COUNT, TIMEOUT, RETRY_COUNT
-
-    DOWNLOAD_DIR = download_dir
-    OUTPUT_FORMAT = output_format
-    COOKIE = cookie
-    USER_AGENT = useragent
-    HTML_VIEWER = html_viewer
-    GENERATE_CBZ = generate_cbz
-    GENERATE_PDF = generate_pdf
-    THREAD_COUNT = thread_count
-    TIMEOUT = timeout
-    RETRY_COUNT = retry_count
-
-    ui.notify('Settings saved', color='positive')
-    dialog.close()
-
-# UI Layout
-with ui.header().classes('bg-primary'):
-    ui.label('nhentai Downloader').classes('text-xl font-bold')
-    ui.space()
-    ui.button('Settings', on_click=show_settings).props('icon=settings flat')
-
-# Input and button row
-with ui.row().classes('w-full items-center mt-4'):
-    id_input = ui.input(label='ID:').classes('mr-2')
-    ui.button('Add ID!', on_click=add_nhentai_id).props('icon=add')
-
-# History section
-ui.label('History').classes('text-xl font-bold mt-4 mb-2')
-history_container = ui.column().classes('w-full border rounded-lg p-2')
-
-# Add some instructions initially
-with history_container:
-    ui.label('Enter an ID and click "Add ID!" to see the history').classes('text-gray-500 italic')
-
-# Add footer with help info
-with ui.footer().classes('bg-gray-100 dark:bg-gray-800 text-sm'):
-    ui.label('Using nhentai CLI tool. Need help? Check the GitHub page:')
-    ui.link('https://github.com/RicterZ/nhentai', 'https://github.com/RicterZ/nhentai').classes('ml-1')
-
-ui.run()