File size: 5,995 Bytes
3ef1dcc
bfa341f
3ec3597
 
bfa341f
 
 
7ef1acd
764130c
3ec3597
 
96d06a6
697c68e
3ec3597
 
 
 
 
 
 
3ef1dcc
764130c
3ef1dcc
bfa341f
96d06a6
212e935
 
3ef1dcc
8b99b89
96d06a6
8b99b89
4c9bee0
96d06a6
 
3ef1dcc
96d06a6
 
 
 
 
 
 
 
fce806c
96d06a6
212e935
 
 
 
 
 
 
 
 
 
96d06a6
212e935
96d06a6
212e935
 
96d06a6
71dd405
96d06a6
71dd405
96d06a6
bfa341f
 
8b99b89
bfa341f
 
96d06a6
bfa341f
 
8b99b89
96d06a6
bfa341f
 
 
8b99b89
96d06a6
7ef1acd
fce806c
96d06a6
 
7ef1acd
 
 
96d06a6
7ef1acd
 
96d06a6
7ef1acd
 
 
 
96d06a6
7ef1acd
 
 
bfa341f
 
3ec3597
 
 
 
5c25007
96d06a6
5c25007
73c1ed7
3ec3597
 
3ef1dcc
2b8e58c
96d06a6
bbeae6c
f8d2244
 
 
 
764130c
 
 
f8d2244
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96d06a6
f8d2244
 
 
 
 
 
 
 
 
 
5dcf7d0
 
3ef1dcc
 
 
f8d2244
3371607
697c68e
021cf6c
3ec3597
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
import mangadex as md
from fastapi import FastAPI, Query, HTTPException
from fastapi.responses import JSONResponse, FileResponse
from fastapi.staticfiles import StaticFiles
from reportlab.pdfgen import canvas
import tempfile
import os
from PIL import Image as PILImage
import httpx
import pikepdf
from pathlib import Path

app = FastAPI()

# Serve static files from the "static" directory
app.mount("/static", StaticFiles(directory="static"), name="static")

# Ensure the "static" directory exists
Path("static").mkdir(exist_ok=True)

auth = md.auth.Auth()

@app.get("/mangadex")
async def fetch_and_upload_pdf(
    chapter_id: str = Query(..., description="Comma-separated MangaDex chapter IDs to fetch images for"),
    as_pdf: bool = Query(True, description="Set to False to return image URLs without creating a PDF"),
    page: str = Query(None, description="Specific page(s) to fetch, e.g., '1' or '1-5'")
):
    """
    Fetch images from specified chapters and optionally combine them into a single PDF.
    """
    try:
        chapter_ids = chapter_id.split(",")
        all_images = []

        # Fetch images for each chapter
        chapter = md.series.Chapter(auth=auth)
        for chapter_id in chapter_ids:
            chapter_data = chapter.get_chapter_by_id(chapter_id=chapter_id)
            images = chapter_data.fetch_chapter_images()
            if not images:
                raise HTTPException(status_code=404, detail=f"No images found for chapter ID {chapter_id}.")
            all_images.extend(images)

        # Filter images by page if applicable
        if page:
            pages = []
            try:
                if '-' in page:
                    start, end = map(int, page.split('-'))
                    pages = list(range(start, end + 1))
                else:
                    pages = [int(page)]
            except ValueError:
                raise HTTPException(status_code=400, detail="Invalid page query format.")
            all_images = [all_images[i - 1] for i in pages if 1 <= i <= len(all_images)]

            if not all_images:
                raise HTTPException(status_code=404, detail="No images found for the selected pages.")

        # Return image URLs if not converting to PDF
        if not as_pdf:
            return JSONResponse(content={"image_urls": all_images})

        # Generate PDF from images
        with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as temp_pdf:
            pdf_path = temp_pdf.name
            c = canvas.Canvas(pdf_path)

            async with httpx.AsyncClient() as client:
                for image_url in all_images:
                    response = await client.get(image_url)
                    response.raise_for_status()

                    # Save image to temporary file
                    with tempfile.NamedTemporaryFile(delete=False, suffix=".jpg") as temp_image:
                        temp_image.write(response.content)
                        temp_image_path = temp_image.name

                    # Process image
                    img = PILImage.open(temp_image_path)
                    img = img.convert("RGB")

                    # Save a converted image (JPEG format)
                    converted_image_path = temp_image_path + "_converted.jpg"
                    img.save(converted_image_path, "JPEG")

                    # Get image dimensions
                    width, height = img.size

                    # Add image to PDF
                    c.setPageSize((width, height))
                    c.drawImage(converted_image_path, 0, 0, width, height)
                    c.showPage()

                    # Clean up temporary files
                    os.remove(temp_image_path)
                    os.remove(converted_image_path)

            c.save()

        # Compress the PDF
        compressed_pdf_path = f"static/{chapter_id}_compressed.pdf"
        with pikepdf.open(pdf_path) as pdf:
            pdf.save(compressed_pdf_path)

        # Clean up temporary PDF file
        os.remove(pdf_path)

        # Return the URL to the compressed PDF
        return JSONResponse(content={"file_url": f"/static/{chapter_id}_compressed.pdf"})

    except Exception as e:
        return JSONResponse(content={"error": f"Failed to process the chapters: {str(e)}"}, status_code=500)

@app.get("/name")
async def fetch_manga_details(
    title: str = Query(..., description="Manga title to search for")
):
    """
    Fetch manga details by title from MangaDex.
    """
    try:
        manga = md.series.Manga(auth=auth)
        manga_list = manga.get_manga_list(title=title)

        if not manga_list:
            return JSONResponse(
                content={"error": f"No manga found with the title '{title}'"},
                status_code=404
            )

        manga_details = []
        for m in manga_list:
            manga_details.append({
                "id": m.manga_id,
                "title": m.title.get("en", "No English Title"),
                "alt_titles": m.altTitles,
                "description": m.description.get("en", "No English Description"),
                "status": m.status,
                "content_rating": m.contentRating,
                "last_volume": m.lastVolume,
                "last_chapter": m.lastChapter,
                "year": m.year,
                "original_language": m.originalLanguage,
                "created_at": str(m.createdAt) if m.createdAt else None,
                "uploaded_at": str(getattr(m, "uploadedAt", None))
            })

        return JSONResponse(content={"manga_list": manga_details})

    except Exception as e:
        return JSONResponse(
            content={"error": f"Failed to fetch manga details: {str(e)}"},
            status_code=500
        )

@app.get("/")
def root():
    """
    Basic root endpoint.
    """
    return {"message": "يعني ايه"}

if __name__ == "__main__":
    import uvicorn
    uvicorn.run("main:app", host="0.0.0.0", port=8000, workers=4)