PinDown: A Python GUI for Downloading from Pinterest
Tags: python, ui, coding, code
Published: 2024-05-19 09:49:18

## PinDown: A Python GUI for Downloading from Pinterest

## Screenshots

![(Add screenshots of your application here if available.)](https://raw.githubusercontent.com/y3script/PinDown/main/Screenshots/PinDown_gui_01.png)
![(Add screenshots of your application here if available.)](https://raw.githubusercontent.com/y3script/PinDown/main/Screenshots/PinDown_gui_02.png)

### Introduction

PinDown is a Python application designed to simplify the process of downloading images and videos from Pinterest. The application leverages `customtkinter` to create an intuitive graphical user interface (GUI), making it accessible for users of all technical levels. This article will walk you through the components and functionality of the PinDown application, explaining how it works and how it can be extended.

### Setting Up the Environment

Before diving into the code, ensure you have the necessary libraries installed. PinDown requires `customtkinter`, `Pillow`, `pypdl`, and other standard libraries. You can install these dependencies using pip:


```pip install customtkinter pillow pypdl```

### Code Overview

The main script for PinDown is structured to create a responsive GUI and handle the download process efficiently. Below is a breakdown of the key components:

### Importing Required Libraries

```python
import customtkinter 
from CTkMessagebox import CTkMessagebox 
from CTkMenuBar import * 
from customtkinter import filedialog 
from PIL import Image 
from Pinterest import Pintrest 
from pypdl import Downloader 
import threading 
import os 
import configparser 
from urllib.parse import urlparse 
import time 
import webbrowser
```

These imports bring in the necessary modules for GUI creation, file handling, image processing, and downloading.

### Setting Up the Appearance

```python
customtkinter.set_appearance_mode("dark") 
customtkinter.set_default_color_theme("dark-blue")
```

The appearance mode is set to dark, and a dark-blue theme is applied to maintain a consistent look and feel throughout the application.

### Main Application Class

The `App` class inherits from `customtkinter.CTk` and serves as the main application window:


```python
class App(customtkinter.CTk):
    def __init__(self):
        super().__init__()
        self.title("PintDown")
        self.geometry('700x250')
        self.iconbitmap("logo.ico")
        self.menu = CTkTitleMenu(self)
        self.file = self.menu.add_cascade("File",hover_color="#b60000")
        self.about = self.menu.add_cascade("About",hover_color="#b60000",command=self.about)
        self.download_folder = CustomDropdownMenu(widget=self.file)
        self.download_folder.add_option(option="Download Folder",command=self.ask_directory)
        self.dl = Downloader()
        self.resizable(False,False)
        img = customtkinter.CTkImage(Image.open("pattern.png"),size=(700,250))
        self.background = customtkinter.CTkLabel(self,image=img)
        self.background.grid(row=0,column=0)
        self.frame = customtkinter.CTkFrame(self.background,width=420,height=500,corner_radius=10)
        self.frame.grid(row=0,column=0)
        self.label = customtkinter.CTkLabel(self.frame,text="PinDown",font=("Helvetica",30))
        self.label.pack(pady=10)
        self.link_enty = customtkinter.CTkEntry(self.frame,width=550,height=40,corner_radius=15)
        self.link_enty.pack(pady=10,padx=30)
        self.frame_progress = customtkinter.CTkFrame(self.frame,width=550,height=30,bg_color="transparent",fg_color="transparent")
        self.frame_progress.pack(pady=10)
        self.download_btn = customtkinter.CTkButton(self.frame,text="Download",corner_radius=12,fg_color="#b60000",hover_color="white",text_color="Black",font=("Helvetica",14),command=lambda: threading.Thread(target=self.download).start())
        self.download_btn.pack(pady=10)
```

### User Interface Setup

1. **Window Title and Size**:
   - The window is titled "PinDown" and given a fixed size of 700x250 pixels.
2. **Menu Bar**:
   - A menu bar is created with "File" and "About" options. The "File" menu contains an option to set the download directory, and the "About" menu displays information about the developer.
3. **Background and Frame**:
   - An image is used as the background, and a central frame is created to hold the main widgets.
4. **Input and Button Widgets**:
   - A label for the title, an entry widget for the Pinterest URL, and a download button are added to the frame.


### Download Functionality

The `download` method handles the downloading process:


```python
def download(self):
        while not os.path.exists("config.ini"):
            self.ask_directory()
        if self.link_enty.get() != "":
            config = configparser.ConfigParser()
            config.read("config.ini")
            download_path = config.get('Download_Path', 'path')
            pin = Pintrest(self.link_enty.get())
            self.download_btn.configure(state="disabled")
            if pin.get_media_Link()["success"]:
                media_link = pin.get_media_Link()['link']
                threading.Thread(target=self.progress_dl).start()
                url_parse = a = urlparse(media_link)
                self.dl.start(media_link,multithread=True,display=False,file_path=os.path.join(download_path,os.path.basename(url_parse.path)))
```

1. **Config File Check**:
   - Ensures a configuration file exists to store the download directory. If not, it prompts the user to select a directory.
2. **Download Path and Pinterest Link**:
   - Reads the download path from the configuration file and gets the media link from the provided Pinterest URL.
3. **Disabling the Download Button**:
   - The download button is disabled to prevent multiple downloads at once.
4. **Starting the Download**:
   - A separate thread is started to handle the download progress.

### Selecting the Download Directory

The `ask_directory` method allows users to choose the download location:


```python
 def ask_directory(self):
        path = filedialog.askdirectory()
        config = configparser.ConfigParser()
        config["Download_Path"] = {"path":path}
        with open("config.ini","w") as configfile:
            config.write(configfile)
```

### Progress Indicator

The `progress_dl` method displays and updates the download progress:


```python
def progress_dl(self):
        self.progress = customtkinter.CTkProgressBar(self.frame_progress,progress_color="#b60000",width=550)
        self.progress.pack(pady=10)
        while self.dl.progress < 100:
            self.progress.set(int(self.dl.progress)/100)
        self.progress.set(1)
        time.sleep(2)
        self.progress.destroy()
        CTkMessagebox(title="success", message="File downloaded successfully",icon="check")
        self.download_btn.configure(state="normal")
```

1. **Progress Bar**:
   - A progress bar is created and updated based on the download progress.
2. **Completion**:
   - Once the download is complete, a success message is displayed, and the download button is re-enabled.

### Running the Application

Finally, the application is started by creating an instance of the `App` class and calling `mainloop()`:


```python
app = App() app.mainloop()
```

### Conclusion

PinDown provides a straightforward solution for downloading media from Pinterest, combining the power of Python with a sleek GUI built using `customtkinter`. The code is modular and can be extended with additional features such as support for more websites or enhanced error handling. Whether you're a developer looking to learn more about Python GUIs or a user wanting an easy way to download Pinterest content, PinDown is a useful tool to explore.

---
## Contact

Made by Y3script. For more info, contact me via [social media](https://bio.link/y3script).
<br>
<br>
[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/L3L2LG5ZV)