├── CTkMessagebox ├── __init__.py ├── ctkmessagebox.py └── icons │ ├── cancel.png │ ├── check.png │ ├── info.png │ ├── question.png │ └── warning.png ├── CTkXYFrame ├── __init__.py └── ctk_xyframe.py ├── README.md ├── Spotify.py ├── Spotify.pyw ├── audiobooks ├── Atomic Habits.mp3 ├── Digital Minimalism.mp3 ├── Essentialism.mp3 ├── Hyperfocus.mp3 ├── Rework.mp3 ├── The Richest Man In Babylon.mp3 └── audiobooksImage │ ├── atomic_habits.png │ ├── digital_minimalism.png │ ├── essentialism.png │ ├── hyperfocus.png │ ├── rework.png │ └── the_richest_man_in_babylon.png ├── avator ├── avator.png ├── avator1.png ├── avator10.png ├── avator11.png ├── avator12.png ├── avator13.png ├── avator14.png ├── avator15.png ├── avator16.png ├── avator17.png ├── avator2.png ├── avator3.png ├── avator4.png ├── avator5.png ├── avator6.png ├── avator7.png ├── avator8.png ├── avator9.png ├── left.png └── right.png ├── extract_info ├── extract_album.py └── extract_artist.py ├── images ├── avator2.png ├── bookopen.png ├── close.png ├── delete.png ├── delete2.png ├── edit.png ├── edit2.png ├── eyes_closed.png ├── eyes_open.png ├── gradient.png ├── headphones.png ├── heart.png ├── heart1.png ├── heart2.png ├── heart3.png ├── home.png ├── icon.png ├── lock.png ├── loop.png ├── mail.png ├── man.png ├── max.png ├── min.png ├── minus.png ├── myHeart.png ├── myHeart2.png ├── myHeart3.png ├── pause.png ├── play.png ├── playlist.png ├── plus.png ├── repeat.png ├── rise.png ├── search.png ├── search2.png ├── settings.png ├── shuffle.png ├── shuffle1.png ├── skip-back.png ├── skip-forward.png ├── song.png ├── spotify.ico ├── spotify.png ├── spotify2.png ├── spotify_bg.png ├── star.png └── x.png ├── requirements.txt ├── singersImage ├── alan_walker.png ├── alec_benjamin.png ├── alisha_chinai.png ├── arijit_singh.png ├── atif_aslam.png ├── duncan_laurence.png ├── g_gayathri_devi.png ├── kina.png ├── kk.png ├── pamphara_thakur.png ├── sachet_tandon.png ├── sarena.png ├── swati_mishra.png └── uma_mohan.png ├── songs ├── Baaton Ko Teri.mp3 ├── Can We Kiss Forever.mp3 ├── Chhod Diya.mp3 ├── Faded.mp3 ├── Fearless.mp3 ├── Hymn For The Weekend.mp3 ├── Infinity.mp3 ├── Into Your Arms.mp3 ├── Khairiyat.mp3 ├── Khamoshiyan.mp3 ├── Let Me Down Slowly.mp3 ├── Phir Mohabbat.mp3 ├── Raghupathi Raghava Rajaram.mp3 ├── Ram Aayenge.mp3 ├── Safari.mp3 ├── See You Again.mp3 ├── Tere Sang Yaara.mp3 ├── Tu Jo Mila.mp3 └── Tum Hi Ho.mp3 └── songs_images ├── arcade.png ├── baaton_ko_teri.png ├── can_we_kiss_forever.png ├── chhod_diya.png ├── chura_ke_dil_mera.png ├── chura_liya_hai_tumne_jo_dil_ko.png ├── dark.png ├── dil_meri_na_sune.png ├── faded.png ├── fearless.png ├── hamari_adhuri_kahani.jpg ├── hamari_adhuri_kahani.png ├── hymn_for_the_weekend.png ├── infinity.png ├── into_your_arms.png ├── khairiyat.png ├── khamoshiyan.png ├── let_me_down_slowly.png ├── phir_mohabbat.png ├── raghupathi_raghava_rajaram.png ├── ram_aayenge.png ├── safari.png ├── see_you_again.png ├── shiv_tandav_stotram.png ├── shree_hari_stotram.png ├── survey.png ├── tera_hone_laga_hoon.png ├── tere_sang_yaara.png ├── theme.png ├── tu_jo_mila.png └── tum_hi_ho.png /CTkMessagebox/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | CustomTkinter Messagebox 3 | Author: Akash Bora 4 | This is a modern messagebox made with customtkinter. 5 | Homepage: https://github.com/Akascape/CTkMessagebox 6 | """ 7 | 8 | __version__ = '2.7' 9 | 10 | from .ctkmessagebox import CTkMessagebox 11 | 12 | -------------------------------------------------------------------------------- /CTkMessagebox/ctkmessagebox.py: -------------------------------------------------------------------------------- 1 | """ 2 | CustomTkinter Messagebox 3 | Author: Akash Bora 4 | Version: 2.7 5 | """ 6 | 7 | import customtkinter 8 | from PIL import Image, ImageTk 9 | import os 10 | import sys 11 | import time 12 | from typing import Literal 13 | 14 | customtkinter.set_appearance_mode("dark") 15 | class CTkMessagebox(customtkinter.CTkToplevel): 16 | ICONS = { 17 | "check": None, 18 | "cancel": None, 19 | "info": None, 20 | "question": None, 21 | "warning": None 22 | } 23 | ICON_BITMAP = {} 24 | def __init__(self, 25 | master: any = None, 26 | width: int = 400, 27 | height: int = 200, 28 | title: str = "CTkMessagebox", 29 | message: str = "This is a CTkMessagebox!", 30 | option_1: str = "OK", 31 | option_2: str = None, 32 | option_3: str = None, 33 | options: list = [], 34 | border_width: int = 1, 35 | border_color: str = "default", 36 | button_color: str = "default", 37 | bg_color: str = "default", 38 | fg_color: str = "default", 39 | text_color: str = "default", 40 | title_color: str = "default", 41 | button_text_color: str = "default", 42 | button_width: int = None, 43 | button_height: int = None, 44 | cancel_button_color: str = None, 45 | cancel_button: str = None, # types: circle, cross or none 46 | button_hover_color: str = "default", 47 | icon: str = "info", 48 | icon_size: tuple = None, 49 | corner_radius: int = 15, 50 | justify: str = "right", 51 | font: tuple = None, 52 | header: bool = False, 53 | topmost: bool = True, 54 | fade_in_duration: int = 0, 55 | sound: bool = False, 56 | wraplength: int = 0, 57 | option_focus: Literal[1, 2, 3] = None): 58 | 59 | super().__init__() 60 | 61 | self.master_window = master 62 | 63 | self.width = 250 if width<250 else width 64 | self.height = 150 if height<150 else height 65 | 66 | if self.master_window is None: 67 | self.spawn_x = int((self.winfo_screenwidth()-self.width)/2) 68 | self.spawn_y = int((self.winfo_screenheight()-self.height)/2) 69 | else: 70 | self.spawn_x = int(self.master_window.winfo_width() * .5 + self.master_window.winfo_x() - .5 * self.width + 7) 71 | self.spawn_y = int(self.master_window.winfo_height() * .5 + self.master_window.winfo_y() - .5 * self.height + 20) 72 | 73 | self.after(10) 74 | self.geometry(f"{self.width}x{self.height}+{self.spawn_x}+{self.spawn_y}") 75 | self.title(title) 76 | self.resizable(width=False, height=False) 77 | self.fade = fade_in_duration 78 | self.oldx = 0 79 | self.oldy = 0 80 | 81 | if self.fade: 82 | self.fade = 20 if self.fade<20 else self.fade 83 | self.attributes("-alpha", 0) 84 | 85 | if not header: 86 | self.overrideredirect(1) 87 | 88 | if topmost: 89 | self.attributes("-topmost", True) 90 | else: 91 | self.transient(self.master_window) 92 | 93 | if sys.platform.startswith("win"): 94 | self.transparent_color = self._apply_appearance_mode(self.cget("fg_color")) 95 | self.attributes("-transparentcolor", self.transparent_color) 96 | default_cancel_button = "cross" 97 | elif sys.platform.startswith("darwin"): 98 | self.transparent_color = 'systemTransparent' 99 | self.attributes("-transparent", True) 100 | default_cancel_button = "circle" 101 | else: 102 | self.transparent_color = '#000001' 103 | corner_radius = 0 104 | default_cancel_button = "cross" 105 | 106 | self.lift() 107 | 108 | self.config(background=self.transparent_color) 109 | self.protocol("WM_DELETE_WINDOW", self.button_event) 110 | self.grid_columnconfigure(0, weight=1) 111 | self.grid_rowconfigure(0, weight=1) 112 | self.x = self.winfo_x() 113 | self.y = self.winfo_y() 114 | self._title = title 115 | self.message = message 116 | self.font = font 117 | self.justify = justify 118 | self.sound = sound 119 | self.cancel_button = cancel_button if cancel_button else default_cancel_button 120 | self.round_corners = corner_radius if corner_radius<=30 else 30 121 | self.button_width = button_width if button_width else self.width/4 122 | self.button_height = button_height if button_height else 28 123 | 124 | if self.fade: self.attributes("-alpha", 0) 125 | 126 | if self.button_height>self.height/4: self.button_height = self.height/4 -20 127 | self.dot_color = cancel_button_color 128 | 129 | self.border_width = border_width if border_width<6 else 5 130 | 131 | if type(options) is list and len(options)>0: 132 | try: 133 | option_1 = options[-1] 134 | option_2 = options[-2] 135 | option_3 = options[-3] 136 | except IndexError: None 137 | 138 | if bg_color=="default": 139 | self.bg_color = self._apply_appearance_mode(customtkinter.ThemeManager.theme["CTkFrame"]["fg_color"]) 140 | else: 141 | self.bg_color = bg_color 142 | 143 | if self.dot_color=="transparent": 144 | self.dot_color = self.bg_color 145 | 146 | if fg_color=="default": 147 | self.fg_color = self._apply_appearance_mode(customtkinter.ThemeManager.theme["CTkFrame"]["top_fg_color"]) 148 | else: 149 | self.fg_color = fg_color 150 | 151 | default_button_color = self._apply_appearance_mode(customtkinter.ThemeManager.theme["CTkButton"]["fg_color"]) 152 | 153 | if sys.platform.startswith("win"): 154 | if self.bg_color==self.transparent_color or self.fg_color==self.transparent_color: 155 | self.configure(fg_color="#000001") 156 | self.transparent_color = "#000001" 157 | self.attributes("-transparentcolor", self.transparent_color) 158 | 159 | if button_color=="default": 160 | self.button_color = (default_button_color, default_button_color, default_button_color) 161 | else: 162 | if type(button_color) is tuple: 163 | if len(button_color)==2: 164 | self.button_color = (button_color[0], button_color[1], default_button_color) 165 | elif len(button_color)==1: 166 | self.button_color = (button_color[0], default_button_color, default_button_color) 167 | else: 168 | self.button_color = button_color 169 | else: 170 | self.button_color = (button_color, button_color, button_color) 171 | 172 | if text_color=="default": 173 | self.text_color = self._apply_appearance_mode(customtkinter.ThemeManager.theme["CTkLabel"]["text_color"]) 174 | else: 175 | self.text_color = text_color 176 | 177 | if title_color=="default": 178 | self.title_color = self._apply_appearance_mode(customtkinter.ThemeManager.theme["CTkLabel"]["text_color"]) 179 | else: 180 | self.title_color = title_color 181 | 182 | if button_text_color=="default": 183 | self.bt_text_color = self._apply_appearance_mode(customtkinter.ThemeManager.theme["CTkButton"]["text_color"]) 184 | else: 185 | self.bt_text_color = button_text_color 186 | 187 | if button_hover_color=="default": 188 | self.bt_hv_color = self._apply_appearance_mode(customtkinter.ThemeManager.theme["CTkButton"]["hover_color"]) 189 | else: 190 | self.bt_hv_color = button_hover_color 191 | 192 | if border_color=="default": 193 | self.border_color = self._apply_appearance_mode(customtkinter.ThemeManager.theme["CTkFrame"]["border_color"]) 194 | else: 195 | self.border_color = border_color 196 | 197 | if icon_size: 198 | self.size_height = icon_size[1] if icon_size[1]<=self.height-100 else self.height-100 199 | self.size = (icon_size[0], self.size_height) 200 | else: 201 | self.size = (self.height/4, self.height/4) 202 | 203 | self.icon = self.load_icon(icon, icon_size) if icon else None 204 | 205 | self.frame_top = customtkinter.CTkFrame(self, corner_radius=self.round_corners, width=self.width, border_width=self.border_width, 206 | bg_color=self.transparent_color, fg_color=self.bg_color, border_color=self.border_color) 207 | self.frame_top.grid(sticky="nswe") 208 | 209 | if button_width: 210 | self.frame_top.grid_columnconfigure(0, weight=1) 211 | else: 212 | self.frame_top.grid_columnconfigure((1,2,3), weight=1) 213 | 214 | if button_height: 215 | self.frame_top.grid_rowconfigure((0,1,3), weight=1) 216 | else: 217 | self.frame_top.grid_rowconfigure((0,1,2), weight=1) 218 | 219 | self.frame_top.bind("", self.move_window) 220 | self.frame_top.bind("", self.oldxyset) 221 | 222 | if self.cancel_button=="cross": 223 | self.button_close = customtkinter.CTkButton(self.frame_top, corner_radius=10, width=0, height=0, hover=False, border_width=0, 224 | text_color=self.dot_color if self.dot_color else self.title_color, 225 | text="✕", fg_color="transparent", command=self.button_event) 226 | self.button_close.grid(row=0, column=5, sticky="ne", padx=5+self.border_width, pady=5+self.border_width) 227 | elif self.cancel_button=="circle": 228 | self.button_close = customtkinter.CTkButton(self.frame_top, corner_radius=10, width=10, height=10, hover=False, border_width=0, 229 | text="", fg_color=self.dot_color if self.dot_color else "#c42b1c", command=self.button_event) 230 | self.button_close.grid(row=0, column=5, sticky="ne", padx=10, pady=10) 231 | 232 | self.title_label = customtkinter.CTkLabel(self.frame_top, width=1, text=self._title, text_color=self.title_color, font=self.font) 233 | self.title_label.grid(row=0, column=0, columnspan=6, sticky="nw", padx=(15,30), pady=5) 234 | self.title_label.bind("", self.move_window) 235 | self.title_label.bind("", self.oldxyset) 236 | 237 | self.info = customtkinter.CTkButton(self.frame_top, width=1, height=self.height/2, corner_radius=0, text=self.message, font=self.font, 238 | fg_color=self.fg_color, hover=False, text_color=self.text_color, image=self.icon) 239 | self.info._text_label.configure(wraplength=self.width/2, justify="left") 240 | self.info.grid(row=1, column=0, columnspan=6, sticky="nwes", padx=self.border_width) 241 | 242 | if wraplength>0: 243 | self.info._text_label.configure(wraplength=wraplength) 244 | 245 | if self.info._text_label.winfo_reqheight()>self.height/2: 246 | height_offset = int((self.info._text_label.winfo_reqheight())-(self.height/2) + self.height) 247 | self.geometry(f"{self.width}x{height_offset}") 248 | 249 | 250 | self.option_text_1 = option_1 251 | 252 | self.button_1 = customtkinter.CTkButton(self.frame_top, text=self.option_text_1, fg_color=self.button_color[0], 253 | width=self.button_width, font=self.font, text_color=self.bt_text_color, 254 | hover_color=self.bt_hv_color, height=self.button_height, 255 | command=lambda: self.button_event(self.option_text_1)) 256 | 257 | 258 | self.option_text_2 = option_2 259 | if option_2: 260 | self.button_2 = customtkinter.CTkButton(self.frame_top, text=self.option_text_2, fg_color=self.button_color[1], 261 | width=self.button_width, font=self.font, text_color=self.bt_text_color, 262 | hover_color=self.bt_hv_color, height=self.button_height, 263 | command=lambda: self.button_event(self.option_text_2)) 264 | 265 | self.option_text_3 = option_3 266 | if option_3: 267 | self.button_3 = customtkinter.CTkButton(self.frame_top, text=self.option_text_3, fg_color=self.button_color[2], 268 | width=self.button_width, font=self.font, text_color=self.bt_text_color, 269 | hover_color=self.bt_hv_color, height=self.button_height, 270 | command=lambda: self.button_event(self.option_text_3)) 271 | 272 | if self.justify=="center": 273 | if button_width: 274 | columns = [4,3,2] 275 | span = 1 276 | else: 277 | columns = [4,2,0] 278 | span = 2 279 | if option_3: 280 | self.frame_top.columnconfigure((0,1,2,3,4,5), weight=1) 281 | self.button_1.grid(row=2, column=columns[0], columnspan=span, sticky="news", padx=(0,10), pady=10) 282 | self.button_2.grid(row=2, column=columns[1], columnspan=span, sticky="news", padx=10, pady=10) 283 | self.button_3.grid(row=2, column=columns[2], columnspan=span, sticky="news", padx=(10,0), pady=10) 284 | elif option_2: 285 | self.frame_top.columnconfigure((0,5), weight=1) 286 | columns = [2,3] 287 | self.button_1.grid(row=2, column=columns[0], sticky="news", padx=(0,5), pady=10) 288 | self.button_2.grid(row=2, column=columns[1], sticky="news", padx=(5,0), pady=10) 289 | else: 290 | if button_width: 291 | self.frame_top.columnconfigure((0,1,2,3,4,5), weight=1) 292 | else: 293 | self.frame_top.columnconfigure((0,2,4), weight=2) 294 | self.button_1.grid(row=2, column=columns[1], columnspan=span, sticky="news", padx=(0,10), pady=10) 295 | elif self.justify=="left": 296 | self.frame_top.columnconfigure((0,1,2,3,4,5), weight=1) 297 | if button_width: 298 | columns = [0,1,2] 299 | span = 1 300 | else: 301 | columns = [0,2,4] 302 | span = 2 303 | if option_3: 304 | self.button_1.grid(row=2, column=columns[2], columnspan=span, sticky="news", padx=(0,10), pady=10) 305 | self.button_2.grid(row=2, column=columns[1], columnspan=span, sticky="news", padx=10, pady=10) 306 | self.button_3.grid(row=2, column=columns[0], columnspan=span, sticky="news", padx=(10,0), pady=10) 307 | elif option_2: 308 | self.button_1.grid(row=2, column=columns[1], columnspan=span, sticky="news", padx=10, pady=10) 309 | self.button_2.grid(row=2, column=columns[0], columnspan=span, sticky="news", padx=(10,0), pady=10) 310 | else: 311 | self.button_1.grid(row=2, column=columns[0], columnspan=span, sticky="news", padx=(10,0), pady=10) 312 | else: 313 | self.frame_top.columnconfigure((0,1,2,3,4,5), weight=1) 314 | if button_width: 315 | columns = [5,4,3] 316 | span = 1 317 | else: 318 | columns = [4,2,0] 319 | span = 2 320 | self.button_1.grid(row=2, column=columns[0], columnspan=span, sticky="news", padx=(0,10), pady=10) 321 | if option_2: 322 | self.button_2.grid(row=2, column=columns[1], columnspan=span, sticky="news", padx=10, pady=10) 323 | if option_3: 324 | self.button_3.grid(row=2, column=columns[2], columnspan=span, sticky="news", padx=(10,0), pady=10) 325 | 326 | if header: 327 | self.title_label.configure(text="") 328 | self.title_label.grid_configure(pady=0) 329 | self.button_close.configure(text_color=self.bg_color) 330 | self.frame_top.configure(corner_radius=0) 331 | 332 | if self.winfo_exists(): 333 | self.grab_set() 334 | 335 | if self.sound: 336 | self.bell() 337 | 338 | if self.fade: 339 | self.fade_in() 340 | 341 | if option_focus: 342 | self.option_focus = option_focus 343 | self.focus_button(self.option_focus) 344 | else: 345 | if not self.option_text_2 and not self.option_text_3: 346 | self.button_1.focus() 347 | self.button_1.bind("", lambda event: self.button_event(self.option_text_1)) 348 | 349 | self.bind("", lambda e: self.button_event()) 350 | 351 | def place_widget(self, widget, x=10, y=10, **args): 352 | if "master" in args: 353 | del args["master"] 354 | 355 | new_widget = widget(master=self.frame_top, **args) 356 | new_widget.place(x=x, y=y) 357 | return new_widget 358 | 359 | def focus_button(self, option_focus): 360 | try: 361 | self.selected_button = getattr(self, "button_"+str(option_focus)) 362 | self.selected_button.focus() 363 | self.selected_button.configure(border_color=self.bt_hv_color, border_width=3) 364 | self.selected_option = getattr(self, "option_text_"+str(option_focus)) 365 | self.selected_button.bind("", lambda event: self.button_event(self.selected_option)) 366 | except AttributeError: 367 | return 368 | 369 | self.bind("", lambda e: self.change_left()) 370 | self.bind("", lambda e: self.change_right()) 371 | 372 | def change_left(self): 373 | if self.option_focus==3: 374 | return 375 | 376 | self.selected_button.unbind("") 377 | self.selected_button.configure(border_width=0) 378 | 379 | if self.option_focus==1: 380 | if self.option_text_2: 381 | self.option_focus = 2 382 | 383 | elif self.option_focus==2: 384 | if self.option_text_3: 385 | self.option_focus = 3 386 | 387 | self.focus_button(self.option_focus) 388 | 389 | def change_right(self): 390 | if self.option_focus==1: 391 | return 392 | 393 | self.selected_button.unbind("") 394 | self.selected_button.configure(border_width=0) 395 | 396 | if self.option_focus==2: 397 | self.option_focus = 1 398 | 399 | elif self.option_focus==3: 400 | self.option_focus = 2 401 | 402 | self.focus_button(self.option_focus) 403 | 404 | def load_icon(self, icon, icon_size): 405 | if icon not in self.ICONS or self.ICONS[icon] is None: 406 | if icon in ["check", "cancel", "info", "question", "warning"]: 407 | image_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'icons', icon + '.png') 408 | else: 409 | image_path = icon 410 | if icon_size: 411 | size_height = icon_size[1] if icon_size[1] <= self.height - 100 else self.height - 100 412 | size = (icon_size[0], size_height) 413 | else: 414 | size = (self.height / 4, self.height / 4) 415 | self.ICONS[icon] = customtkinter.CTkImage(Image.open(image_path), size=size) 416 | self.ICON_BITMAP[icon] = ImageTk.PhotoImage(file=image_path) 417 | if not sys.platform.startswith("darwin"): 418 | self.after(200, lambda: self.iconphoto(False, self.ICON_BITMAP[icon])) 419 | return self.ICONS[icon] 420 | 421 | def fade_in(self): 422 | for i in range(0,110,10): 423 | if not self.winfo_exists(): 424 | break 425 | self.attributes("-alpha", i/100) 426 | self.update() 427 | time.sleep(1/self.fade) 428 | 429 | def fade_out(self): 430 | for i in range(100,0,-10): 431 | if not self.winfo_exists(): 432 | break 433 | self.attributes("-alpha", i/100) 434 | self.update() 435 | time.sleep(1/self.fade) 436 | 437 | def get(self): 438 | if self.winfo_exists(): 439 | self.master.wait_window(self) 440 | return self.event 441 | 442 | def oldxyset(self, event): 443 | self.oldx = event.x 444 | self.oldy = event.y 445 | 446 | def move_window(self, event): 447 | self.y = event.y_root - self.oldy 448 | self.x = event.x_root - self.oldx 449 | self.geometry(f'+{self.x}+{self.y}') 450 | 451 | def button_event(self, event=None): 452 | try: 453 | self.button_1.configure(state="disabled") 454 | self.button_2.configure(state="disabled") 455 | self.button_3.configure(state="disabled") 456 | except AttributeError: 457 | pass 458 | 459 | if self.fade: 460 | self.fade_out() 461 | self.grab_release() 462 | self.destroy() 463 | self.event = event 464 | if self.master_window: 465 | self.master_window.focus_force() 466 | 467 | if __name__ == "__main__": 468 | app = CTkMessagebox() 469 | app.mainloop() 470 | -------------------------------------------------------------------------------- /CTkMessagebox/icons/cancel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/CTkMessagebox/icons/cancel.png -------------------------------------------------------------------------------- /CTkMessagebox/icons/check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/CTkMessagebox/icons/check.png -------------------------------------------------------------------------------- /CTkMessagebox/icons/info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/CTkMessagebox/icons/info.png -------------------------------------------------------------------------------- /CTkMessagebox/icons/question.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/CTkMessagebox/icons/question.png -------------------------------------------------------------------------------- /CTkMessagebox/icons/warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/CTkMessagebox/icons/warning.png -------------------------------------------------------------------------------- /CTkXYFrame/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | CustomTkinter XY scrollable frame 3 | Author: Akash Bora (Akascape) 4 | License: MIT 5 | Homepage: https://github.com/Akascape/CTkXYFrame 6 | """ 7 | 8 | __version__ = '0.2' 9 | 10 | from .ctk_xyframe import CTkXYFrame 11 | -------------------------------------------------------------------------------- /CTkXYFrame/ctk_xyframe.py: -------------------------------------------------------------------------------- 1 | """ 2 | Advanced scrollable frame for customtkinter 3 | Author: Akash Bora 4 | License: MIT 5 | """ 6 | 7 | import customtkinter 8 | from tkinter import Canvas 9 | 10 | class CTkXYFrame(customtkinter.CTkFrame): 11 | def __init__(self, 12 | master: any, 13 | scrollbar_fg_color = None, 14 | scrollbar_button_color = None, 15 | scrollbar_button_hover_color = None, 16 | **kwargs): 17 | 18 | self.parent_frame = customtkinter.CTkFrame(master=master, **kwargs) 19 | self.bg_color = self.parent_frame.cget("fg_color") 20 | self.xy_canvas = Canvas(self.parent_frame, bg=self.parent_frame._apply_appearance_mode(self.bg_color), borderwidth=0, highlightthickness=0) 21 | self.parent_frame.rowconfigure(0,weight=1) 22 | self.parent_frame.columnconfigure(0,weight=1) 23 | 24 | customtkinter.CTkFrame.__init__(self, master=self.xy_canvas, fg_color=self.parent_frame.cget("fg_color"), 25 | bg_color=self.parent_frame.cget("fg_color")) 26 | self.xy_canvas.create_window((0,0), window=self, anchor="nw") 27 | 28 | self.vsb = customtkinter.CTkScrollbar(self.parent_frame, orientation="vertical", command=self.xy_canvas.yview, 29 | fg_color=scrollbar_fg_color, button_color=scrollbar_button_color, 30 | button_hover_color=scrollbar_button_hover_color) 31 | self.hsb = customtkinter.CTkScrollbar(self.parent_frame, orientation="horizontal", command=self.xy_canvas.xview, 32 | fg_color=scrollbar_fg_color, button_color=scrollbar_button_color, 33 | button_hover_color=scrollbar_button_hover_color) 34 | 35 | self.xy_canvas.configure(yscrollcommand=lambda x,y: self.dynamic_scrollbar_vsb(x,y), 36 | xscrollcommand=lambda x,y: self.dynamic_scrollbar_hsb(x,y)) 37 | self.xy_canvas.grid(row=0, column=0, sticky="nsew", padx=(7,0), pady=(7,0)) 38 | 39 | self.bind("", lambda event, canvas=self.xy_canvas: self.onFrameConfigure(canvas)) 40 | self.xy_canvas.bind_all("", lambda e: self._on_mousewheel(e.delta)) 41 | self.xy_canvas.bind_all("", lambda e: self._on_mousewheel_shift(e.delta)) 42 | self.xy_canvas.bind_all("", lambda e: self._on_mousewheel(120)) 43 | self.xy_canvas.bind_all("", lambda e: self._on_mousewheel(-120)) 44 | self.xy_canvas.bind_all("", lambda e: self._on_mousewheel_shift(120)) 45 | self.xy_canvas.bind_all("", lambda e: self._on_mousewheel_shift(-120)) 46 | 47 | def destroy(self): 48 | customtkinter.CTkFrame.destroy(self) 49 | self.parent_frame.destroy() 50 | 51 | def _set_appearance_mode(self, mode_string): 52 | super()._set_appearance_mode(mode_string) 53 | self.xy_canvas.config(bg=self.parent_frame._apply_appearance_mode(self.bg_color)) 54 | 55 | def dynamic_scrollbar_vsb(self, x, y): 56 | if float(x)==0.0 and float(y)==1.0: 57 | self.vsb.grid_forget() 58 | else: 59 | self.vsb.grid(row=0, column=1, rowspan=2, sticky="nse", pady=5) 60 | self.vsb.set(x,y) 61 | 62 | def dynamic_scrollbar_hsb(self, x, y): 63 | if float(x)==0.0 and float(y)==1.0: 64 | self.hsb.grid_forget() 65 | else: 66 | self.hsb.grid(row=1, column=0, sticky="nwe", padx=(5,0)) 67 | self.hsb.set(x,y) 68 | 69 | def onFrameConfigure(self, canvas): 70 | canvas.configure(scrollregion=canvas.bbox("all")) 71 | 72 | def _on_mousewheel(self, event): 73 | self.xy_canvas.yview_scroll(int(-1*(event/120)), "units") 74 | 75 | def _on_mousewheel_shift(self, event): 76 | self.xy_canvas.xview_scroll(int(-1*(event/120)), "units") 77 | 78 | def pack(self, **kwargs): 79 | self.parent_frame.pack(**kwargs) 80 | 81 | def place(self, **kwargs): 82 | self.parent_frame.place(**kwargs) 83 | 84 | def grid(self, **kwargs): 85 | self.parent_frame.grid(**kwargs) 86 | 87 | def pack_forget(self): 88 | self.parent_frame.pack_forget() 89 | 90 | def place_forget(self, **kwargs): 91 | self.parent_frame.place_forget() 92 | 93 | def grid_forget(self, **kwargs): 94 | self.parent_frame.grid_forget() 95 | 96 | def grid_remove(self, **kwargs): 97 | self.parent_frame.grid_remove() 98 | 99 | def grid_propagate(self, **kwargs): 100 | self.parent_frame.grid_propagate() 101 | 102 | def grid_info(self, **kwargs): 103 | return self.parent_frame.grid_info() 104 | 105 | def lift(self, aboveThis=None): 106 | self.parent_frame.lift(aboveThis) 107 | 108 | def lower(self, belowThis=None): 109 | self.parent_frame.lower(belowThis) 110 | 111 | def configure(self, **kwargs): 112 | if "fg_color" in kwargs: 113 | self.bg_color = kwargs["fg_color"] 114 | self.xy_canvas.config(bg=self.bg_color) 115 | self.configure(fg_color=self.bg_color) 116 | self.parent_frame.configure(**kwargs) 117 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Spotify 2 | ## A modern music player using Python and CustomTkitner 3 | 4 | Here to install the required modules : - 5 | ``` 6 | pip install customtkinter 7 | ``` 8 | 9 | ``` 10 | pip install tkinter 11 | ``` 12 | 13 | ``` 14 | pip install mutagen 15 | ``` 16 | 17 | ``` 18 | pip install pygame 19 | ``` 20 | 21 | ``` 22 | pip install eyed3 23 | ``` 24 | ## First UI Design : - 25 | 26 | ![First Screen](https://github.com/SarthakTools/Spotify/assets/114976722/ba07bcee-d209-42d2-a5e2-f7a69996d227) 27 | 28 | ![Screenshot (10)](https://github.com/SarthakTools/Spotify/assets/114976722/7b570eeb-777d-4231-ab6c-c2becc8c691c) 29 | 30 | ![Screenshot (11)](https://github.com/SarthakTools/Spotify/assets/114976722/92c32ebc-70c9-49b2-b2e0-fc5f13259e08) 31 | 32 | ![Screenshot (13)](https://github.com/SarthakTools/Spotify/assets/114976722/8191a6dd-84a4-425c-a947-e0c13b217a27) 33 | 34 | ![Screenshot (14)](https://github.com/SarthakTools/Spotify/assets/114976722/bc612781-42cc-429b-a4cc-9dd16c408603) 35 | 36 | ![Screenshot (15)](https://github.com/SarthakTools/Spotify/assets/114976722/32c978c7-b7ee-4f51-b7c3-1e2755860cf4) 37 | 38 | ![Screenshot (16)](https://github.com/SarthakTools/Spotify/assets/114976722/43d36d18-189f-45ac-8a20-d6f9dc7c112c) 39 | 40 | ![Screenshot (17)](https://github.com/SarthakTools/Spotify/assets/114976722/88205fea-3540-497f-8394-3b275c159d67) 41 | 42 | ![Screenshot (18)](https://github.com/SarthakTools/Spotify/assets/114976722/ca58ee9c-f342-4d5a-9905-8e840d1117df) 43 | 44 | ![Screenshot (19)](https://github.com/SarthakTools/Spotify/assets/114976722/53b03338-0a13-487e-992a-e45bfcc8f39d) 45 | 46 | ![Screenshot (20)](https://github.com/SarthakTools/Spotify/assets/114976722/fd285be2-769c-4e67-95c3-a80ab3a6c0c0) 47 | 48 | ![Screenshot (21)](https://github.com/SarthakTools/Spotify/assets/114976722/5448d8de-8ccd-4060-a9a5-b5c2c47afbc2) 49 | -------------------------------------------------------------------------------- /Spotify.py: -------------------------------------------------------------------------------- 1 | import os, cProfile, pygame, time, random, threading 2 | from tkinter import BOTH, LEFT, RIGHT, TOP, BOTTOM, X, Y, CENTER 3 | import customtkinter as ct 4 | from CTkXYFrame import CTkXYFrame 5 | from PIL import Image 6 | from mutagen.mp3 import MP3 7 | from extract_info.extract_artist import get_artist 8 | from ctypes import windll 9 | from CTkMessagebox import CTkMessagebox 10 | from tkinter import Toplevel 11 | 12 | ct.set_default_color_theme("green") 13 | ct.set_appearance_mode("dark") 14 | 15 | class IntroPage: 16 | def __init__(self, root): 17 | self.root = root 18 | self.root.title("Spotfiy - A modern music player built with Python") 19 | self.root.geometry("550x300") 20 | self.root.iconbitmap("images\\spotify.ico") 21 | self.root.overrideredirect(True) 22 | 23 | with open("imagename.txt", "w") as f: 24 | f.write("avator.png") 25 | 26 | image_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "images") 27 | spotify_image = ct.CTkImage(Image.open(os.path.join(image_path, "spotify.png")), size=(90, 90)) 28 | 29 | ct.CTkLabel(self.root, text=" Spotify", image=spotify_image, compound=LEFT, font=("Poppins", 60, "bold")).pack(padx=10, pady=120, anchor="center") 30 | 31 | self.text = ct.CTkLabel(self.root, text="Please wait...The First launch of the app may take longer...", font=("IBM Plex Sans", 15)) 32 | self.progressbar = ct.CTkProgressBar(self.root, orientation="horizontal", width=300, mode="determinate", determinate_speed=0.35, 33 | fg_color="white", height=8, progress_color="#1ED765", corner_radius=0) 34 | self.progressbar.pack(side=BOTTOM, fill=X) 35 | self.text.pack(side=BOTTOM, anchor="center") 36 | 37 | self.progressbar.set(0) 38 | self.progressbar.start() 39 | 40 | self.thread = threading.Thread(target=self.loading) 41 | self.thread.start() 42 | self.set_appwindow(self.root) 43 | self.center_window(self.root) 44 | 45 | def loading(self): 46 | time.sleep(3) 47 | self.text.configure(text="") 48 | self.text.configure(text="Please wait.....The First launch of the app may take longer...") 49 | self.progressbar.stop() 50 | self.progressbar.set(100) 51 | self.main() 52 | 53 | def center_window(self, win): 54 | win.update_idletasks() 55 | width = win.winfo_width() 56 | height = win.winfo_height() 57 | x = (win.winfo_screenwidth() // 2) - (width // 2) 58 | y = (win.winfo_screenheight() // 2) - (height // 2) 59 | win.geometry('{}x{}+{}+{}'.format(width, height, x, y)) 60 | 61 | def set_appwindow(self, mainWindow): 62 | GWL_EXSTYLE = -20 63 | WS_EX_APPWINDOW = 0x00040000 64 | WS_EX_TOOLWINDOW = 0x00000080 65 | hwnd = windll.user32.GetParent(mainWindow.winfo_id()) 66 | stylew = windll.user32.GetWindowLongW(hwnd, GWL_EXSTYLE) 67 | stylew = stylew & ~WS_EX_TOOLWINDOW 68 | stylew = stylew | WS_EX_APPWINDOW 69 | res = windll.user32.SetWindowLongW(hwnd, GWL_EXSTYLE, stylew) 70 | mainWindow.wm_withdraw() 71 | mainWindow.after(10, lambda: mainWindow.wm_deiconify()) 72 | 73 | def main(self): 74 | for widget in self.root.winfo_children(): 75 | widget.destroy() 76 | 77 | LoginPage(root) 78 | 79 | class LoginPage: 80 | def __init__(self, root): 81 | self.root = root 82 | self.root.overrideredirect(False) 83 | self.root.title("Spotify - Login to play songs for free") 84 | self.root.geometry("1000x600+200+40") 85 | self.root.configure(fg_color="#1b1717") 86 | self.root.resizable(False, False) 87 | 88 | Height = 12 89 | Width = 300 90 | icon_size = 35 91 | 92 | image_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "images") 93 | spotify_image = ct.CTkImage(Image.open(os.path.join(image_path, "spotify2.png")), size=(100, 75)) 94 | email_image = ct.CTkImage(Image.open(os.path.join(image_path, "mail.png")), size=(icon_size, icon_size)) 95 | password_image = ct.CTkImage(Image.open(os.path.join(image_path, "lock.png")), size=(icon_size, icon_size)) 96 | 97 | self.loginframe = ct.CTkFrame(self.root, fg_color="#111", corner_radius=15) 98 | 99 | ct.CTkLabel(self.loginframe, text="Spotify", image=spotify_image, compound=LEFT, font=("monospace", 40, "bold"), text_color="white").pack(pady=30, side=TOP, anchor="nw", padx=100) 100 | 101 | ct.CTkLabel(self.loginframe, text="Music for everyone", font=("monospace", 30, "bold"), text_color="white").pack(pady=15) 102 | 103 | self.username_frame = ct.CTkFrame(self.loginframe, height=0, width=0, fg_color="#333") 104 | ct.CTkLabel(self.username_frame, text="", image=email_image, fg_color="transparent", corner_radius=0).pack(side=LEFT, padx=10) 105 | self.usernameInput = ct.CTkEntry(self.username_frame, placeholder_text="Email or username", font=("monospace", 20, "bold"), 106 | height=Height, width=Width, text_color="#f3f3f3", fg_color="transparent", border_width=0) 107 | self.usernameInput.pack(side=LEFT, ipady=15) 108 | self.username_frame.pack(pady=10, ipadx=10, ipady=2) 109 | 110 | self.password_frame = ct.CTkFrame(self.loginframe, height=0, width=0, fg_color="#333") 111 | ct.CTkLabel(self.password_frame, text="", image=password_image, fg_color="transparent", corner_radius=0).pack(side=LEFT, padx=10) 112 | self.passwordInput = ct.CTkEntry(self.password_frame, placeholder_text="Password", font=("monospace", 20, "bold"), 113 | height=Height, width=Width, text_color="white", fg_color="transparent", border_width=0, show="*") 114 | self.passwordInput.pack(side=LEFT, ipady=15) 115 | self.password_frame.pack(pady=5, ipadx=10, ipady=2) 116 | 117 | self.loginBtn = ct.CTkButton(self.loginframe, text="LOG IN", text_color="black", font=("monospace", 20, "bold"), fg_color="white", corner_radius=10, 118 | hover_color="#dcdada", command=self.login) 119 | self.loginBtn.pack(side=TOP, fill=X, padx=55, pady=10, ipady=10) 120 | 121 | self.loginframe.pack(side=TOP, fill=BOTH, expand=True, pady=40, padx=260) 122 | 123 | progressbar_frame = ct.CTkFrame(self.loginframe, height=0, width=0, fg_color="transparent") 124 | self.progressbar = ct.CTkProgressBar(self.loginframe, orientation="horizontal", mode="determinate", determinate_speed=0.6, 125 | fg_color="white", height=5, progress_color="#1ED765", corner_radius=0, ) 126 | self.progressbar.set(0) 127 | self.progressbar.pack(side=BOTTOM, fill=X) 128 | progressbar_frame.pack(side=BOTTOM, fill=X) 129 | 130 | self.thread = threading.Thread(target=self.loading) 131 | 132 | def login(self): 133 | username = self.usernameInput.get() 134 | password = self.passwordInput.get() 135 | 136 | if len(username) == 0 or len(password) == 0: 137 | CTkMessagebox(title="Error", message=" Username or Password can't be empty ", icon="cancel", font=("monospace", 15, "bold"), text_color="white", wraplength=600) 138 | else: 139 | if len(password) > 8: 140 | CTkMessagebox(title="Error", message=" Password should not be more than 8 digits", icon="cancel", font=("monospace", 15, "bold"), text_color="white", wraplength=600) 141 | else: 142 | with open("data.txt", "w") as f: 143 | user_name = username.split("@")[0] 144 | data = {"name" : user_name, "password" : password, "email" : f"{user_name}@spotify.com"} 145 | f.write(str(data)) 146 | 147 | self.progressbar.start() 148 | self.thread.start() 149 | 150 | def loading(self): 151 | time.sleep(1.5) 152 | self.progressbar.stop() 153 | self.progressbar.set(100) 154 | 155 | for widget in self.root.winfo_children(): 156 | widget.destroy() 157 | 158 | app = Spotify(self.root) 159 | add_music(app) 160 | 161 | class AvatorPageTopLevel: 162 | def __init__(self, master, on_close_callback=False): 163 | self.on_close_callback = on_close_callback 164 | self.profile_window = ct.CTkToplevel(master, fg_color="black") 165 | self.profile_window.iconbitmap("images\\spotify.ico") 166 | self.profile_window.title("Select your avator for profile") 167 | 168 | toplevel_width = 750 169 | toplevel_height = 450 170 | x = (master.winfo_screenwidth() // 2) - (toplevel_width // 2) 171 | y = (master.winfo_screenheight() // 2) - (toplevel_height // 2) 172 | self.profile_window.geometry(f"{toplevel_width}x{toplevel_height}+{x}+{y}") 173 | 174 | self.profile_window.resizable(False, False) 175 | self.profile_window.attributes("-topmost", True) 176 | self.profile_window.grab_set() 177 | 178 | self.avator_images = [] 179 | image_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "avator") 180 | 181 | for i in range(1, 17): 182 | self.avator_images.append(ct.CTkImage(Image.open(os.path.join(image_path, f"avator{i}.png")), size=(200, 200))) 183 | 184 | self.current_avator_index = 0 185 | 186 | avator_frame = ct.CTkFrame(self.profile_window, fg_color="transparent") 187 | ct.CTkLabel(avator_frame, text="Select your Avator", font=("Canbera", 45, "bold"), text_color="white").pack(side=TOP, fill=X, anchor="nw", padx=0, pady=10) 188 | 189 | avator1 = self.avator_images[0] 190 | avator2 = self.avator_images[1] 191 | avator3 = self.avator_images[2] 192 | avator4 = self.avator_images[3] 193 | avator5 = self.avator_images[4] 194 | avator6 = self.avator_images[5] 195 | avator7 = self.avator_images[6] 196 | 197 | icon_right = ct.CTkImage(Image.open(os.path.join(image_path, "right.png")), size=(50, 50)) 198 | icon_left = ct.CTkImage(Image.open(os.path.join(image_path, "left.png")), size=(50, 50)) 199 | 200 | self.left_button = ct.CTkButton(avator_frame, text="", image=icon_left, fg_color="transparent", width=0, hover_color="#222", command=self.change_avator_left) 201 | self.left_button.pack(side=LEFT, padx=5) 202 | self.avator = ct.CTkButton(avator_frame, text="", image=avator1, width=1, height=1, fg_color="transparent", hover_color="#000", corner_radius=50) 203 | self.avator.pack(side=LEFT, anchor="center", padx=120) 204 | self.right_button = ct.CTkButton(avator_frame, text="", image=icon_right, fg_color="transparent", width=0, hover_color="#222", command=self.change_avator_right) 205 | self.right_button.pack(side=RIGHT, padx=5) 206 | 207 | self.progressbar = ct.CTkProgressBar(self.profile_window, orientation="horizontal", width=300, mode="determinate", determinate_speed=0.9, fg_color="#333", height=5, progress_color="#1ED765", corner_radius=0) 208 | self.progressbar.pack(side=BOTTOM, fill=X) 209 | self.progressbar.set(0) 210 | 211 | self.select = ct.CTkButton(self.profile_window, text="Select", font=("monospace", 23, "normal"), height=50, width=150, command=self.select_avator) 212 | self.select.pack(side=BOTTOM, anchor="center", pady=20) 213 | 214 | avator_frame.pack(side=TOP, fill=X, padx=80, pady=30, ipadx=50, ipady=20) 215 | 216 | self.profile_window.mainloop() 217 | 218 | def select_avator(self): 219 | self.avator.configure(fg_color="#222", hover_color="#222") 220 | image = f"avator{self.current_avator_index+1}.png" 221 | with open("imagename.txt", "w") as f: 222 | f.write(image) 223 | self.select.configure(text=" Processing...", state="disabled") 224 | self.progressbar.start() 225 | self.profile_window.after(1000, self.loading) 226 | 227 | def loading(self): 228 | time.sleep(0.5) 229 | self.profile_window.after(0, self.close_window) 230 | 231 | def close_window(self): 232 | self.profile_window.destroy() 233 | if self.on_close_callback(): 234 | self.on_close_callback() 235 | 236 | def change_avator_right(self): 237 | self.avator.configure(fg_color="transparent", hover_color="black") 238 | self.current_avator_index = (self.current_avator_index + 1) % len(self.avator_images) 239 | self.avator.configure(image=self.avator_images[self.current_avator_index]) 240 | 241 | def change_avator_left(self): 242 | self.avator.configure(fg_color="transparent", hover_color="black") 243 | self.current_avator_index = (self.current_avator_index - 1) % len(self.avator_images) 244 | self.avator.configure(image=self.avator_images[self.current_avator_index]) 245 | 246 | class Spotify: 247 | def __init__(self, root): 248 | self.root = root 249 | self.root.title("Spotify") 250 | self.root.geometry("1300x700") 251 | self.root.minsize(1300, 700) 252 | self.bg_color = "#202124" 253 | self.root.configure(fg_color=self.bg_color) 254 | self.root.resizable(True, True) 255 | self.root.iconbitmap("images\\spotify.ico") 256 | # pywinstyles.apply_style(self, style="acrylic") 257 | 258 | # Load images from the images folder 259 | image_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "images") 260 | self.spotify_img = ct.CTkImage(Image.open(os.path.join(image_path, "spotify.png")), size=(50, 50)) 261 | self.home_img = ct.CTkImage(Image.open(os.path.join(image_path, "home.png")), size=(25, 25)) 262 | self.discover_img = ct.CTkImage(Image.open(os.path.join(image_path, "song.png")), size=(25, 25)) 263 | self.rise_img = ct.CTkImage(Image.open(os.path.join(image_path, "rise.png")), size=(25, 20)) 264 | self.rise_img2 = ct.CTkImage(Image.open(os.path.join(image_path, "search2.png")), size=(20, 20)) 265 | self.audiobooks_img = ct.CTkImage(Image.open(os.path.join(image_path, "headphones.png")), size=(25, 25)) 266 | self.audiobooks_img2 = ct.CTkImage(Image.open(os.path.join(image_path, "bookopen.png")), size=(45, 45)) 267 | self.settings_img = ct.CTkImage(Image.open(os.path.join(image_path, "settings.png")), size=(25, 25)) 268 | self.search_img = ct.CTkImage(Image.open(os.path.join(image_path, "search.png")), size=(30, 30)) 269 | self.add_img = ct.CTkImage(Image.open(os.path.join(image_path, "plus.png")), size=(33, 33)) 270 | self.delete_img = ct.CTkImage(Image.open(os.path.join(image_path, "delete2.png")), size=(28, 28)) 271 | self.edit_img = ct.CTkImage(Image.open(os.path.join(image_path, "edit.png")), size=(28, 28)) 272 | self.favourite_img3 = ct.CTkImage(Image.open(os.path.join(image_path, "star.png")), size=(28, 28)) 273 | self.eyes_icon_open = ct.CTkImage(Image.open(os.path.join(image_path, "eyes_open.png")), size=(20, 20)) 274 | self.eyes_icon_closed = ct.CTkImage(Image.open(os.path.join(image_path, "eyes_closed.png")), size=(20, 20)) 275 | 276 | self.image_path_avatar = os.path.join(os.path.dirname(os.path.realpath(__file__)), "avator") 277 | with open("imagename.txt", "r") as f: 278 | profile_image = f.read() 279 | self.profile_img = ct.CTkImage(Image.open(os.path.join(self.image_path_avatar, profile_image)), size=(35, 35)) # avator profile 280 | self.avator_image = ct.CTkImage(Image.open(os.path.join(self.image_path_avatar, profile_image)), size=(155, 155)) # avator profile 281 | 282 | self.nav_frame = ct.CTkFrame(self.root, fg_color="#141517") 283 | 284 | self.spotify_label = ct.CTkLabel(self.nav_frame, text=" Spotify ", text_color="white", image=self.spotify_img, compound=LEFT, 285 | font=("Poppins", 30)) 286 | self.spotify_label.pack(side=TOP, padx=10, pady=5) 287 | 288 | ct.CTkLabel(self.nav_frame, text="").pack(pady=5) 289 | 290 | self.search = ct.CTkButton(self.nav_frame, text="Search", width=50, height=40, fg_color="transparent", hover_color="#444", 291 | corner_radius=10, image=self.search_img, font=("Montserrat", 20), text_color="white", anchor="w", command=lambda: self.select_frame_name("search")) 292 | self.search.pack(side=TOP, pady=5, ipady=5, padx=5, fill=X) 293 | 294 | ct.CTkButton(self.nav_frame, text="", fg_color="transparent", hover_color="#141517", text_color="white").pack(side=TOP, pady=10, fill=X) 295 | 296 | self.home = ct.CTkButton(self.nav_frame, text="Home", width=50, height=40, fg_color="transparent", hover_color="#444", 297 | corner_radius=10, image=self.home_img, font=("Montserrat", 20), text_color="white", anchor="w", command=lambda: self.select_frame_name("home")) 298 | self.home.pack(side=TOP, pady=5, ipady=5, padx=5, fill=X) 299 | 300 | self.artists = ct.CTkButton(self.nav_frame, text="Artists", width=50, height=40, fg_color="transparent", hover_color="#444", 301 | corner_radius=10, image=self.discover_img, font=("Montserrat", 20), text_color="white", anchor="w", command=lambda: self.select_frame_name("artists")) 302 | self.artists.pack(side=TOP, pady=5, ipady=5, padx=5, fill=X) 303 | 304 | self.trending = ct.CTkButton(self.nav_frame, text="Trending", width=50, height=40, fg_color="transparent", hover_color="#444", 305 | corner_radius=10, image=self.rise_img, font=("Montserrat", 20), text_color="white", anchor="w", command=lambda: self.select_frame_name("trending")) 306 | self.trending.pack(side=TOP, pady=5, ipady=5, padx=5, fill=X) 307 | 308 | self.audiobooks = ct.CTkButton(self.nav_frame, text="AudioBooks", width=50, height=40, fg_color="transparent", hover_color="#444", 309 | corner_radius=10, image=self.audiobooks_img, font=("Montserrat", 20), text_color="white", anchor="w", command=lambda: self.select_frame_name("audiobooks")) 310 | self.audiobooks.pack(side=TOP, pady=5, ipady=5, padx=5, fill=X) 311 | 312 | self.favourites_btn = ct.CTkButton(self.nav_frame, text="Favourites", width=50, height=40, fg_color="transparent", hover_color="#444", 313 | corner_radius=10, image=self.favourite_img3, font=("Montserrat", 20), text_color="white", anchor="w", command=lambda: self.select_frame_name("favourites")) 314 | self.favourites_btn.pack(side=TOP, pady=5, ipady=5, padx=5, fill=X) 315 | 316 | self.settings = ct.CTkButton(self.nav_frame, text="Settings", width=50, height=40, fg_color="transparent", hover_color="#444", 317 | corner_radius=10, image=self.settings_img, font=("Montserrat", 20), text_color="white", anchor="w", command=lambda: self.select_frame_name("settings")) 318 | self.settings.pack(side=BOTTOM, pady=10, ipady=5, padx=5, fill=X) 319 | 320 | self.nav_frame.pack(side=LEFT, fill=Y) 321 | 322 | self.main = ct.CTkFrame(self.root, corner_radius=0, fg_color=self.bg_color) 323 | self.main.pack(fill=BOTH, expand=True) 324 | 325 | # Create all the frames for every tab inside the main frame 326 | self.color_home_frame = "#333" 327 | 328 | # Search frame code here ......................... 329 | self.search_frame = ct.CTkFrame(self.main, corner_radius=0, fg_color="#555") 330 | self.search_label = ct.CTkLabel(self.search_frame, text="", image=self.search_img) 331 | 332 | self.search_box = ct.CTkEntry(self.search_frame, font=("IBM Plex Sans", 23), placeholder_text="What do you want to play today ?", placeholder_text_color="#a5a5a5", 333 | corner_radius=10, border_width=0, fg_color=self.bg_color, text_color="white") 334 | self.search_box.pack(side=TOP, fill=X, ipady=15, padx=20, pady=20) 335 | self.search_box.bind("", self.on_button_release) 336 | 337 | self.like_that_entry = ct.CTkEntry(self.search_frame, width=0, height=0, fg_color="#555", text_color="#555", bg_color="#555", border_width=0) 338 | self.like_that_entry.pack(side=BOTTOM, fill=X) 339 | self.search_frame.bind("", lambda event: self.like_that_entry.focus()) 340 | 341 | self.all_songs_name = ['Arcade', 'Can We Kiss Forever', 'Faded', 342 | 'Fearless', 'Hymn For The Weekend', 'Infinity', 'Into Your Arms', 'Khairiyat', 343 | 'Let Me Down Slowly', 'Phir Mohabbat', 'Raghupathi Raghava Rajaram', 344 | 'Ram Aayenge', 'Safari', 'See You Again','Tere Sang Yaara', 345 | 'Tu Jo Mila', 'Tum Hi Ho', 'Chhod Diya'] 346 | 347 | self.searching_frame = ct.CTkFrame(self.search_frame, fg_color="#333") 348 | self.searching_frame.pack(side=TOP, fill=X, padx=20, pady=10) 349 | 350 | #---------------------------------------------------------------------------------------------------- 351 | 352 | self.home_frame = CTkXYFrame(self.main, corner_radius=0, fg_color=self.color_home_frame) 353 | 354 | self.home_label = ct.CTkLabel(self.home_frame, text="Home", font=("Poppins", 50), text_color="white") 355 | self.home_label.pack(anchor="nw", side=TOP, padx=20) 356 | 357 | self.discover_frame = ct.CTkFrame(self.main, corner_radius=0, fg_color="#1f1e42") 358 | self.popular_frame = ct.CTkFrame(self.main, corner_radius=0, fg_color=self.color_home_frame) 359 | self.audiobooks_frame = ct.CTkFrame(self.main, corner_radius=0, fg_color=self.color_home_frame) 360 | self.settings_frame = ct.CTkFrame(self.main, corner_radius=0, fg_color=self.color_home_frame) 361 | self.favourites_frame = ct.CTkFrame(self.main, corner_radius=0, fg_color=self.color_home_frame) 362 | 363 | ##################### ---------- Artists code ---------------- ################################### 364 | 365 | self.artist_frame = ct.CTkScrollableFrame(self.discover_frame, fg_color="transparent") 366 | singer_image_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "singersImage") 367 | ariijt_image = ct.CTkImage(Image.open(os.path.join(singer_image_path, "arijit_singh.png")), size=(250, 250)) 368 | gayathri_image = ct.CTkImage(Image.open(os.path.join(singer_image_path, "g_gayathri_devi.png")), size=(250, 250)) 369 | kk_image = ct.CTkImage(Image.open(os.path.join(singer_image_path, "kk.png")), size=(250, 250)) 370 | atif_alsam_image = ct.CTkImage(Image.open(os.path.join(singer_image_path, "atif_aslam.png")), size=(250, 250)) 371 | alisha_chinai_image = ct.CTkImage(Image.open(os.path.join(singer_image_path, "alisha_chinai.png")), size=(250, 250)) 372 | sachet_tandon_image = ct.CTkImage(Image.open(os.path.join(singer_image_path, "sachet_tandon.png")), size=(250, 250)) 373 | pamphara_thakur_image = ct.CTkImage(Image.open(os.path.join(singer_image_path, "pamphara_thakur.png")), size=(250, 250)) 374 | swati_mishra_image = ct.CTkImage(Image.open(os.path.join(singer_image_path, "swati_mishra.png")), size=(250, 250)) 375 | alan_walker_image = ct.CTkImage(Image.open(os.path.join(singer_image_path, "alan_walker.png")), size=(250, 250)) 376 | alec_benjamin_image = ct.CTkImage(Image.open(os.path.join(singer_image_path, "alec_benjamin.png")), size=(250, 250)) 377 | duncan_laurence_image = ct.CTkImage(Image.open(os.path.join(singer_image_path, "duncan_laurence.png")), size=(250, 250)) 378 | kina_image = ct.CTkImage(Image.open(os.path.join(singer_image_path, "kina.png")), size=(250, 250)) 379 | # uma_mohan_image = ct.CTkImage(Image.open(os.path.join(singer_image_path, "uma_mohan.png")), size=(250, 250)) 380 | 381 | ct.CTkLabel(self.discover_frame, text="Artists", font=("Heleventica", 55, "bold")).pack(side=TOP, anchor="ne", fill=X, pady=5) 382 | 383 | row_1 = ct.CTkFrame(self.artist_frame, fg_color="transparent") 384 | arijit_singh = ct.CTkLabel(row_1, text="Arijit Singh", font=("IBM Plex Sans", 20, "bold"), image=ariijt_image, compound=TOP) 385 | arijit_singh.pack(side=LEFT, padx=25) 386 | g_gayahatri = ct.CTkLabel(row_1, text="G. Gayathri Devi", font=("IBM Plex Sans", 20, "bold"), image=gayathri_image, compound=TOP) 387 | g_gayahatri.pack(side=LEFT, padx=25) 388 | kk = ct.CTkLabel(row_1, text="Krishnakumar Kunnath", font=("IBM Plex Sans", 20, "bold"), image=kk_image, compound=TOP) 389 | kk.pack(side=LEFT, padx=25) 390 | atif_alsam = ct.CTkLabel(row_1, text="Atif Aslam", font=("IBM Plex Sans", 20, "bold"), image=atif_alsam_image, compound=TOP) 391 | atif_alsam.pack(side=LEFT, padx=25) 392 | row_1.pack(fill=X, side=TOP) 393 | 394 | row_2 = ct.CTkFrame(self.artist_frame, fg_color="transparent") 395 | alisha_chinai = ct.CTkLabel(row_2, text="Alisha Chinai", font=("IBM Plex Sans", 20, "bold"), image=alisha_chinai_image, compound=TOP) 396 | alisha_chinai.pack(side=LEFT, padx=25) 397 | sachet_tandon = ct.CTkLabel(row_2, text="Sachet Tandon", font=("IBM Plex Sans", 20, "bold"), image=sachet_tandon_image, compound=TOP) 398 | sachet_tandon.pack(side=LEFT, padx=25) 399 | pamphara_thakur = ct.CTkLabel(row_2, text="Parampara Thakur", font=("IBM Plex Sans", 20, "bold"), image=pamphara_thakur_image, compound=TOP) 400 | pamphara_thakur.pack(side=LEFT, padx=25) 401 | swati_mishra = ct.CTkLabel(row_2, text="Swati Mishra", font=("IBM Plex Sans", 20, "bold"), image=swati_mishra_image, compound=TOP) 402 | swati_mishra.pack(side=LEFT, padx=25) 403 | 404 | row_2.pack(fill=X, side=TOP, pady=20) 405 | 406 | row_3 = ct.CTkFrame(self.artist_frame, fg_color="transparent") 407 | 408 | alan_walker = ct.CTkLabel(row_3, text="Alan Walker", font=("IBM Plex Sans", 20, "bold"), image=alan_walker_image, compound=TOP) 409 | alan_walker.pack(side=LEFT, padx=25) 410 | alec_benjemin = ct.CTkLabel(row_3, text="Alec Benjamin", font=("IBM Plex Sans", 20, "bold"), image=alec_benjamin_image, compound=TOP) 411 | alec_benjemin.pack(side=LEFT, padx=25) 412 | duncan_laurence = ct.CTkLabel(row_3, text="Duncan Laurence", font=("IBM Plex Sans", 20, "bold"), image=duncan_laurence_image, compound=TOP) 413 | duncan_laurence.pack(side=LEFT, padx=25) 414 | kina = ct.CTkLabel(row_3, text="Kina Cosper", font=("IBM Plex Sans", 20, "bold"), image=kina_image, compound=TOP) 415 | kina.pack(side=LEFT, padx=25) 416 | 417 | row_3.pack(side=TOP, fill=X) 418 | 419 | self.artist_frame.pack(side=TOP, fill=BOTH, expand=True, padx=20, pady=40) 420 | 421 | 422 | # settings frame code ################################## 423 | 424 | self.profile_frame = ct.CTkFrame(self.settings_frame, fg_color=self.bg_color) 425 | self.profile_button = ct.CTkButton(self.profile_frame, text="", width=0, corner_radius=0, fg_color=self.bg_color, hover_color="#333", image=self.profile_img, command=self.changeProfilePhoto) 426 | self.profile_button.pack(side=RIGHT) 427 | 428 | self.username = ct.CTkLabel(self.profile_frame, text="Username", font=("IBM Plex Sans", 25, "bold")) 429 | self.username.pack(anchor="center", side=LEFT, padx=15) 430 | 431 | self.profile_frame.pack(side=TOP, fill=X, ipady=10, padx=5, pady=2, ipadx=10) 432 | 433 | # settings control frame all the settings 434 | self.settings_control_frame = ct.CTkFrame(self.settings_frame, fg_color=self.bg_color) 435 | 436 | ct.CTkLabel(self.settings_control_frame, text="Settings", font=("IBM Plex Sans", 40, "bold")).pack(side=TOP, anchor="nw", padx=20, pady=20) 437 | 438 | # auto update frame 439 | self.update_frame = ct.CTkFrame(self.settings_control_frame) 440 | self.update_btn = ct.CTkSwitch(self.update_frame, text="", switch_height=30, switch_width=60, font=("Poppins", 40, "bold")) 441 | upadte_text = ct.CTkLabel(self.update_frame, text="Auto-Update", font=("IBM Plex Sans", 25, "bold")) 442 | upadte_text.pack(side=LEFT, padx=20) 443 | self.update_btn.pack(side=RIGHT, padx=2) 444 | self.update_frame.pack(side=TOP, fill=X, padx=15, ipady=10) 445 | self.update_frame.bind("", self.toggle_update) 446 | 447 | # account frame 448 | self.account_frame = ct.CTkFrame(self.settings_control_frame) 449 | 450 | with open("data.txt", "r") as f: 451 | data = f.readline().strip() 452 | 453 | try: data_dict = eval(data) 454 | except Exception: data_dict = {} 455 | 456 | email_value = data_dict.get("email") 457 | password_value = data_dict.get("password") 458 | 459 | name = data_dict.get("name") 460 | self.username.configure(text=name) 461 | 462 | self.email = data_dict.get("email") if email_value else "username@spotify.com" 463 | self.password = data_dict.get("password") if password_value else "12345678" 464 | 465 | self.account_details_frame = ct.CTkFrame(self.account_frame, fg_color="transparent") 466 | ct.CTkLabel(self.account_details_frame, text="Account", font=("Poppins", 30, "bold")).pack(side=TOP, anchor="nw", padx=10) 467 | 468 | details_frame = ct.CTkFrame(self.account_details_frame, fg_color="transparent") 469 | 470 | self.email_label = ct.CTkLabel(details_frame, text=f"Email-ID : {self.email}", font=("IBM Plex Sans", 20, "bold")) 471 | 472 | password_frame = ct.CTkFrame(details_frame, fg_color="transparent") 473 | self.password_label = ct.CTkLabel(password_frame, text=f"Password : ", font=("IBM Plex Sans", 20, "bold")) 474 | self.password_input = ct.CTkLabel(password_frame, font=("consolas", 20, "bold"), text="********") 475 | self.icon_eyes = ct.CTkButton(password_frame, text="", image=self.eyes_icon_closed, width=0, font=("consolas", 100), fg_color="transparent", hover_color=self.bg_color, command=self.show_password) 476 | self.password_label.pack(side=LEFT) 477 | self.password_input.pack(side=LEFT) 478 | self.icon_eyes.pack(side=LEFT, padx=5) 479 | 480 | self.email_label.pack(side=TOP, anchor="nw") 481 | password_frame.pack(side=TOP, anchor="nw") 482 | 483 | details_frame.pack(side=LEFT, pady=10, padx=10) 484 | self.account_details_frame.pack(side=LEFT, fill=BOTH, expand=True, pady=10, padx=10) 485 | 486 | self.photo_frame = ct.CTkLabel(self.account_frame, text="", image=self.avator_image, fg_color="transparent") 487 | self.photo_frame.pack(side=RIGHT, padx=40, fill=BOTH, ipadx=10, pady=10) 488 | 489 | self.delete_account = ct.CTkButton(details_frame, text="Delete Account", font=("Poppins", 20, "bold"), fg_color="#e15455", hover_color="#f44344", corner_radius=10, bg_color="transparent", command=self.deleteAccount) 490 | self.delete_account.pack(side=TOP, anchor="nw", ipady=7, pady=5) 491 | 492 | self.account_frame.pack(side=TOP, fill=X, padx=15, ipady=10, pady=10) 493 | 494 | # about frame 495 | self.about_frame = ct.CTkFrame(self.settings_control_frame) 496 | 497 | ct.CTkLabel(self.about_frame, text="About", font=("IBM Plex Sans", 40, "bold")).pack(side=TOP, anchor="nw", padx=20, pady=20) 498 | ct.CTkLabel(self.about_frame, text="About : © 2024 Spotify Limited. All rights reserved", font=("consolas", 20, "bold")).pack(side=TOP, anchor="nw", padx=20) 499 | ct.CTkLabel(self.about_frame, text="Version : 1.1", font=("consolas", 20, "bold")).pack(side=TOP, anchor="nw", padx=20) 500 | ct.CTkLabel(self.about_frame, text="Developer : Sarthak Singh", font=("consolas", 20, "bold")).pack(side=TOP, anchor="nw", padx=20) 501 | 502 | self.about_frame.pack(side=TOP, fill=BOTH, padx=15, pady=5, ipady=20) 503 | 504 | self.settings_control_frame.pack(side=TOP, fill=BOTH, expand=True, padx=5, pady=10) 505 | 506 | self.music_playing = None 507 | self.frames = {} # Dictionary to store frames for each tab 508 | self.frames2 = {} # Dictionary to store frames for each tab 509 | # control song frame 510 | 511 | # global stop_img, pause_img 512 | song_image_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "images") 513 | self.pause_img = ct.CTkImage(Image.open(os.path.join(song_image_path, "pause.png")), size= (35, 35)) 514 | self.stop_img = ct.CTkImage(Image.open(os.path.join(song_image_path, "play.png")), size= (35, 35)) 515 | self.skip_forward_img = ct.CTkImage(Image.open(os.path.join(song_image_path, "skip-forward.png")), size= (35, 35)) 516 | self.skip_backward_img = ct.CTkImage(Image.open(os.path.join(song_image_path, "skip-back.png")), size= (35, 35)) 517 | self.loop_img = ct.CTkImage(Image.open(os.path.join(image_path, "loop.png")), size=(36, 36)) 518 | self.shuffle_img = ct.CTkImage(Image.open(os.path.join(image_path, "shuffle.png")), size=(28, 28)) 519 | self.favourite_img = ct.CTkImage(Image.open(os.path.join(image_path, "myHeart.png")), size=(35, 35)) 520 | self.favourite_img2 = ct.CTkImage(Image.open(os.path.join(image_path, "myHeart2.png")), size=(35, 35)) 521 | song_image_path2 = os.path.join(os.path.dirname(os.path.realpath(__file__)), "songs_images") 522 | self.imgPlaylistFavourites = ct.CTkImage(Image.open(os.path.join(song_image_path2, "dark.png")), size=(250, 220)) 523 | 524 | self.control_frame = ct.CTkFrame(self.root, corner_radius=10, fg_color="transparent") 525 | 526 | self.image_song_label = ct.CTkLabel(self.control_frame, text="", fg_color="#555", height=54, width=54, corner_radius=5) 527 | self.image_song_label.pack(side=LEFT, padx=10) 528 | 529 | self.slide_time_frame = ct.CTkFrame(self.control_frame, fg_color="transparent") 530 | 531 | self.time_elapsed_label = ct.CTkLabel(self.slide_time_frame, text="00:00", font=("Poppins", 20)) 532 | self.time_elapsed_label.pack(side=LEFT, padx=10) 533 | 534 | self.music_duration_label = ct.CTkLabel(self.slide_time_frame, text="00:00", font=("Poppins", 20)) 535 | self.music_duration_label.pack(side=RIGHT, padx=10) 536 | 537 | self.slider = ct.CTkSlider(self.slide_time_frame, height=20, fg_color="#4b5d4b", progress_color="#106A43", bg_color="transparent", 538 | command=lambda event: self.slide_song(), from_=0, to=100) 539 | self.slider.pack(fill=X, padx=20) 540 | self.slider.set(0) 541 | 542 | self.slide_time_frame.pack(side=TOP, fill=X) 543 | 544 | ######################################### 545 | 546 | # playlist frame code --------------------- 547 | 548 | self.audiobooks_heading_frame = ct.CTkFrame(self.audiobooks_frame, corner_radius=8, fg_color="#222") 549 | ct.CTkLabel(self.audiobooks_heading_frame, text=" AudioBooks", image=self.audiobooks_img2, font=("Poppins", 30, "bold"), 550 | compound=LEFT, text_color="white").pack(side=LEFT, padx=10, ipady=5, ipadx=10) 551 | self.audiobooks_heading_frame.pack(side=TOP, fill=X, pady=5, padx=10, ipady=10) 552 | 553 | self.audio_frame = ct.CTkScrollableFrame(self.audiobooks_frame) 554 | self.audio_frame.pack(side=TOP, fill=BOTH, expand=True, padx=10, pady=10) 555 | 556 | self.playlist_container = ct.CTkScrollableFrame(self.favourites_frame, fg_color="#202128", corner_radius=10) 557 | self.playlist_container.pack(fill=BOTH, expand=True, padx=5, pady=2) 558 | 559 | self.favourites_playlist = ct.CTkFrame(self.playlist_container, fg_color="#333") 560 | self.favourites_playlist.pack(side=TOP, padx=5, ipady=15, pady=5, fill=X) 561 | 562 | # --------------------- playlist code ................. 563 | ######################################################## 564 | # Play control frame for the control of music 565 | 566 | self.singer_name = ct.CTkLabel(self.control_frame, text="Singer name", font=("IBM Plex Sans", 20, "bold"), text_color="#a5a5a5") 567 | self.singer_name.pack(side=LEFT, padx=10) 568 | 569 | self.play_control_frame = ct.CTkFrame(self.control_frame, fg_color="#212228", width=0) 570 | 571 | self.loop = ct.CTkButton(self.play_control_frame, text="", image=self.loop_img, width=0, fg_color="transparent", command=self.loop_song) 572 | self.loop.pack(side=LEFT, padx=80) 573 | 574 | self.skip_backward = ct.CTkButton(self.play_control_frame, text="", image=self.skip_backward_img, width=0, fg_color="transparent", corner_radius=5, bg_color="transparent", command=self.play_previous_song) 575 | self.skip_backward.pack(side=LEFT) 576 | self.pause = ct.CTkButton(self.play_control_frame, text="", image=self.stop_img, width=0, fg_color="transparent", corner_radius=5, bg_color="transparent", command=self.stop_music, state="disabled") 577 | self.pause.pack(side=LEFT) 578 | self.skip_forward = ct.CTkButton(self.play_control_frame, text="", image=self.skip_forward_img, width=0, fg_color="transparent", corner_radius=5, bg_color="transparent", command=self.play_previous_song) 579 | self.skip_forward.pack(side=LEFT) 580 | 581 | self.favourite = ct.CTkButton(self.play_control_frame, text="", image=self.favourite_img, width=0, fg_color="transparent", 582 | command=self.add_favourite) 583 | self.favourite.pack(side=RIGHT, padx=80) 584 | 585 | self.play_control_frame.pack(side=LEFT, padx=140) 586 | 587 | self.control_frame.pack(side=BOTTOM, fill=X, pady=10) 588 | 589 | self.trends_frame = ct.CTkFrame(self.popular_frame, fg_color="#241d48", bg_color="#241d48") 590 | 591 | ct.CTkLabel(self.trends_frame, text="Popular ", font=("IBM Plex Sans", 40, "bold")).pack(side=TOP, anchor="nw", padx=35, pady=20) 592 | 593 | self.trending_song_frame = ct.CTkFrame(self.trends_frame, fg_color="transparent") 594 | trending_songs = self.generate_random_song(10) 595 | 596 | for i, trends in enumerate(trending_songs): 597 | i+=1 598 | ct.CTkButton(self.trending_song_frame, text=f"{i}. {trends}", font=("Poppins", 21, "normal"), 599 | anchor="w", corner_radius=10, fg_color="#3d375a", hover_color="#464d75", command=lambda song=trends: self.play_music(f"{song}.mp3")).pack(side=TOP, fill=X, ipady=10, padx=10, pady=5) 600 | 601 | self.trending_song_frame.pack(side=TOP, fill=X, padx=20, pady=10) 602 | 603 | self.trends_frame.pack(fill=BOTH, expand=True) 604 | 605 | self.all_songs = [] 606 | self.playlists = [] 607 | self.favourites = [] 608 | self.previous_song = [] 609 | 610 | # Focus the home tab first 611 | self.select_frame_name("home") 612 | 613 | self.position = 0 614 | self.loop = False 615 | self.music_scale = False 616 | 617 | self.root.bind("", self.spacebar_event) 618 | self.open_favourites() 619 | self.updateFavouritePlaylistImage() 620 | 621 | intital_songs = self.generate_random_song(10) 622 | for item in intital_songs: 623 | ct.CTkButton(self.searching_frame, text=f" {item}", width=20, font=("Poppins", 21, "normal"), command=lambda item=item: self.on_button_click(item), 624 | anchor="w", corner_radius=0, fg_color="#333", text_color="#c7c3c3", image=self.rise_img2, hover_color="#444").pack(fill=X, pady=0, ipady=10, padx=5) 625 | 626 | def changeProfilePhoto(self): 627 | def callBack(): 628 | with open("imagename.txt", "r") as f: 629 | image_name = f.read() 630 | profile_img = ct.CTkImage(Image.open(os.path.join(self.image_path_avatar, image_name)), size=((35, 35))) 631 | avator_img = ct.CTkImage(Image.open(os.path.join(self.image_path_avatar, image_name)), size=((155, 155))) 632 | self.profile_button.configure(image=profile_img) 633 | self.photo_frame.configure(image=avator_img) 634 | AvatorPageTopLevel(self.root, on_close_callback=callBack) 635 | 636 | def deleteAccount(self): 637 | if os.path.exists("data.txt"): 638 | msg = CTkMessagebox(title="Delete Account", message=" Are you sure to delete account ? Restart the program to create new account.", icon="question", font=("monospace", 15, "bold"), text_color="white", wraplength=550, option_1="Cancel", option_2="No", option_3="Yes", width=550) 639 | 640 | if msg.get() == "Yes": 641 | msg = CTkMessagebox(title="Delete Account", message="Your account has been deleted", icon="check", option_1="Thanks", cancel_button="circle", cancel_button_color="red") 642 | if msg.get() == "Thanks": 643 | os.remove("data.txt") 644 | self.root.destroy() 645 | else: 646 | pass 647 | 648 | def generate_random_song(self, number): 649 | return random.sample(self.all_songs_name, number) 650 | 651 | def search_filter(self, search_term): 652 | for widget in self.searching_frame.winfo_children(): 653 | widget.destroy() 654 | 655 | if search_term == "": 656 | initial_fruits = self.generate_random_song(8) 657 | for item in initial_fruits: 658 | ct.CTkButton(self.searching_frame, text=f" {item}", width=20, font=("Poppins", 21, "normal"), command=lambda item=item: self.on_button_click(item), 659 | anchor="w", corner_radius=0, fg_color="#333", text_color="#c7c3c3", image=self.rise_img2, hover_color="#444").pack(fill=X, pady=0, ipady=10, padx=5) 660 | else: 661 | filtered_data = [item for item in self.all_songs_name if item.lower().startswith(search_term.lower())] 662 | filtered_data.sort() 663 | for item in filtered_data: 664 | ct.CTkButton(self.searching_frame, text=f" {item}", width=20, font=("Poppins", 21, "normal"), command=lambda item=item: self.on_button_click(item), 665 | anchor="w", corner_radius=0, fg_color="#333", text_color="#c7c3c3", image=self.rise_img2, hover_color="#444").pack(fill=X, pady=0, ipady=10, padx=5) 666 | 667 | def on_button_click(self, item): 668 | music_name = f"{item}.mp3" 669 | self.play_music(music_name) 670 | 671 | def on_button_release(self, event): 672 | search_term = event.widget.get() 673 | self.search_filter(search_term) 674 | 675 | def show_password(self): 676 | self.icon_eyes.configure(image=self.eyes_icon_open, command=self.hide_password) 677 | self.password_input.configure(text=self.password) 678 | 679 | def hide_password(self): 680 | self.icon_eyes.configure(image=self.eyes_icon_closed, command=self.show_password) 681 | self.password_input.configure(text="********") 682 | 683 | def toggle_update(self, event): 684 | self.update_btn.toggle() 685 | 686 | def playPlaylist_song(self): 687 | for music_name in self.favourites: 688 | pygame.mixer.music.load(f"songs\\{music_name}") 689 | pygame.mixer.music.play() 690 | self.insertSongImage(music_name) 691 | self.configure_music(music_name) 692 | self.previous_song.append(music_name) 693 | artist_name = self.get_music_info(f"songs\\{music_name}")["artist"] 694 | self.singer_name.configure(text=artist_name) 695 | 696 | if len(artist_name) > 16: 697 | self.play_control_frame.pack_configure(padx=20) 698 | if len(artist_name) < 16: 699 | self.play_control_frame.pack_configure(padx=140) 700 | 701 | self.favourite.pack(side=RIGHT, padx=80) 702 | 703 | def open_favourites(self): 704 | global playlist_songs_frame, music_name, image_path, title_song 705 | image_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "songs_images") 706 | self.favourites_playlist.pack_forget() 707 | self.playlist_container.pack_forget() 708 | self.favourites_playlist_full = ct.CTkScrollableFrame(self.favourites_frame, fg_color="#222029") 709 | 710 | self.title_frame = ct.CTkFrame(self.favourites_playlist_full) 711 | self.title_frame.pack(side=TOP, fill=X) 712 | 713 | title_song = ct.CTkLabel(self.title_frame, text="", bg_color="transparent", corner_radius=10) 714 | title_song.pack(side=LEFT, pady=10) 715 | 716 | space = ct.CTkLabel(self.title_frame, text="") 717 | space.pack(side=TOP, anchor="nw", pady=20, padx=10) 718 | 719 | title = ct.CTkLabel(self.title_frame, text="Favourites", font=("Poppins", 50, "bold"), text_color="white") 720 | title.pack(side=TOP, anchor="nw", pady=20, padx=10) 721 | 722 | play = ct.CTkButton(self.title_frame, text="Play ", image=self.stop_img, font=("IBM Plex Sans", 30, "bold"), text_color="white", 723 | corner_radius=60, fg_color="#2d862d", hover_color="#2c7c2c", command=self.playPlaylist_song) 724 | play.pack(side=TOP, anchor="nw", padx=10, ipady=10, ipadx=10) 725 | 726 | if len(self.favourites) > 0: 727 | music_name = self.favourites[0].lower().replace(" ", "_") 728 | music_name = music_name.split(".") 729 | music_name[1] = ".png" 730 | music_name = str(music_name[0] + music_name[1]) 731 | title_image = ct.CTkImage(Image.open(os.path.join(image_path, f"{music_name}")), size=(250, 220)) 732 | title_song.configure(image=title_image) 733 | 734 | if len(self.favourites) == 0: 735 | title_song.configure(image=self.imgPlaylistFavourites) 736 | 737 | ######################################################### 738 | playlist_songs_frame = ct.CTkFrame(self.favourites_playlist_full, fg_color="transparent") 739 | 740 | for i in self.favourites: 741 | list_fav_song_frame = ct.CTkFrame(playlist_songs_frame, fg_color="#444") 742 | photo_name = self.favourites[0].lower().replace(" ", "_") 743 | photo_name = photo_name.split(".") 744 | photo_name[1] = ".png" 745 | photo_name = str(photo_name[0]) 746 | photo = ct.CTkImage(Image.open(os.path.join(image_path, f"{music_name}")), size=(40, 40)) 747 | 748 | songs_favourite = ct.CTkButton(list_fav_song_frame, text=i.split(".")[0], fg_color="transparent", hover_color="#444", font=("Poppins", 22, "bold"), 749 | image=photo, compound=LEFT, text_color="white") 750 | songs_favourite.pack(side=LEFT, fill=X, padx=10) 751 | 752 | singer_name = ct.CTkLabel(list_fav_song_frame, text=self.get_music_info(f"songs\\{i}")["artist"], font=("Poppins", 20, "bold")) # type: ignore 753 | singer_name.pack(side=RIGHT, padx=20) 754 | 755 | list_fav_song_frame.pack(side=TOP, fill=X, expand=False, ipady=10, padx=10, pady=10, ipadx=10) 756 | playlist_songs_frame.pack(side=BOTTOM, fill=X, expand=True, pady=10, padx=5) 757 | ######################################################### 758 | 759 | self.favourites_playlist_full.pack(side=TOP, fill=BOTH, expand=True, padx=10, pady=10) 760 | 761 | def update_songs_(self): 762 | global playlist_songs_frame 763 | i = len(self.favourites) 764 | if i == 0: 765 | playlist_songs_frame.destroy() 766 | else: 767 | playlist_songs_frame.destroy() 768 | playlist_songs_frame = ct.CTkFrame(self.favourites_playlist_full, fg_color="transparent") 769 | for i in self.favourites: 770 | list_fav_song_frame = ct.CTkFrame(playlist_songs_frame, fg_color="#444") 771 | photo_name = i.lower().replace(" ", "_") 772 | photo_name = photo_name.split(".") 773 | photo_name[1] = ".png" 774 | photo_name = str(photo_name[0]) 775 | photo = ct.CTkImage(Image.open(os.path.join(image_path, f"{photo_name}.png")), size=(40, 40)) 776 | songs_favourite = ct.CTkButton(list_fav_song_frame, text=i.split(".")[0], fg_color="transparent", hover_color="#444", font=("Poppins", 22, "bold"), 777 | image=photo, compound=LEFT, text_color="white") 778 | songs_favourite.pack(side=LEFT, fill=X, padx=10) 779 | 780 | singer_name = ct.CTkLabel(list_fav_song_frame, text=self.get_music_info(f"songs\\{i}")["artist"], font=("Poppins", 20, "bold")) # type: ignore 781 | singer_name.pack(side=RIGHT, padx=20) 782 | 783 | list_fav_song_frame.pack(side=TOP, fill=X, expand=False, ipady=10, padx=10, pady=10, ipadx=10) 784 | playlist_songs_frame.pack(side=BOTTOM, fill=X, expand=True, pady=10, padx=5) 785 | 786 | def updateFavouritePlaylistImage(self): 787 | global music_icon, image_path, title_song 788 | image_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "songs_images") 789 | if len(self.favourites) > 0: 790 | music_name = self.favourites[0].lower().replace(" ", "_") 791 | music_name = music_name.split(".") 792 | music_name[1] = ".png" 793 | music_name = str(music_name[0] + music_name[1]) 794 | music_icon = ct.CTkImage(Image.open(os.path.join(image_path, f"{music_name}")), size=(220, 220)) 795 | title_song.configure(image=music_icon) 796 | 797 | if len(self.favourites) == 0: 798 | title_song.configure(image=self.imgPlaylistFavourites) 799 | 800 | self.root.after(1000, self.updateFavouritePlaylistImage) 801 | 802 | def play_previous_song(self): 803 | try: 804 | self.play_music(self.previous_song[len(self.previous_song)-2]) 805 | except Exception as e: 806 | print(e) 807 | 808 | def loop_song(self): 809 | self.loop = True 810 | if self.music_playing: 811 | current_position = pygame.mixer.music.get_pos() / 1000 812 | # print(current_position) 813 | 814 | def add_favourite(self): 815 | if self.music_playing: 816 | if self.music_playing not in self.favourites: 817 | self.favourite.configure(image=self.favourite_img2) 818 | self.favourite.configure(command=self.remove_favourite) 819 | self.favourites.append(self.music_playing) 820 | self.update_songs_() 821 | else: 822 | pass 823 | 824 | def remove_favourite(self): 825 | if self.music_playing: 826 | try: 827 | self.favourite.configure(image=self.favourite_img) 828 | self.favourite.configure(command=self.add_favourite) 829 | self.favourites.remove(self.music_playing) 830 | self.updateFavouritePlaylistImage() 831 | self.update_songs_() 832 | except Exception as e: 833 | print(e) 834 | 835 | def spacebar_event(self, event): 836 | if self.music_playing: 837 | self.stop_music() 838 | self.root.bind("", self.spacebar_event_2) 839 | 840 | def spacebar_event_2(self, event): 841 | self.resume_music() 842 | self.root.bind("", self.spacebar_event) 843 | 844 | def slide_song(self): 845 | # if self.music_playing: 846 | # music_file = f"songs\\{self.music_playing}" 847 | # pygame.mixer.music.load(music_file) 848 | # music_length = pygame.mixer.Sound(music_file).get_length() 849 | # scale_at = int(self.slider.get()) / 100 * music_length 850 | # pygame.mixer.music.play(start=int(scale_at)) 851 | pass 852 | 853 | def get_music_info(self, music_name): 854 | artist = get_artist(music_name) 855 | # album = get_album(song) 856 | 857 | return { 858 | "artist" : artist, 859 | # "album" : album 860 | } 861 | 862 | def add_Music(self, music_name, music_image_name, tab="home"): 863 | self.all_songs.append(music_name) 864 | global song_image_path, song_img 865 | song_image_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "songs_images") 866 | song_img = ct.CTkImage(Image.open(os.path.join(song_image_path, music_image_name)), size=(280, 230)) 867 | 868 | if tab not in self.frames: 869 | self.frames[tab] = ct.CTkFrame(self.home_frame, fg_color=self.color_home_frame) 870 | 871 | song_button = ct.CTkButton(self.frames[tab], text=music_name, fg_color=self.color_home_frame, bg_color="transparent", corner_radius=10, 872 | image=song_img, command=lambda: self.play_music(f"{music_name}.mp3"), compound=TOP, font=("IBM Plex Sans", 20)) 873 | song_button.pack(side=LEFT, ipady=10, ipadx=0) 874 | self.frames[tab].pack(side=TOP, fill=X, pady=2) 875 | 876 | def add_audiobooks(self, audiobook_name, audiobook_image_name, tab="audiobooks"): 877 | global audiobooks_image_path, audiobook_img 878 | audiobooks_image_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "audiobooks\\audiobooksImage") 879 | audiobook_img = ct.CTkImage(Image.open(os.path.join(audiobooks_image_path, audiobook_image_name)), size=(190, 250)) 880 | 881 | if tab not in self.frames2: 882 | self.frames2[tab] = ct.CTkFrame(self.audio_frame, fg_color="transparent") 883 | 884 | audiobook_button = ct.CTkButton(self.frames2[tab], text="", fg_color="transparent", bg_color="transparent", hover_color="gray30", image=audiobook_img, command=lambda: self.play_audiobooks(audiobook_name)) 885 | audiobook_button.pack(side=LEFT, ipady=10, ipadx=8, padx=10) 886 | self.frames2[tab].pack(side=TOP, fill=X, pady=10, padx=30) 887 | 888 | def play_audiobooks(self, audiobook_name): 889 | self.favourite.pack_forget() 890 | author = {"Atomic Habits" : "James Clear", 891 | "Digital Minimalism" : "Cal Newport", 892 | "Rework" : "Jason Fried", 893 | "HyperFocus" : "Chris Bailey", 894 | "The Richest Man in Babylon" : "George Clason", 895 | "Essentialism" : "Greg Mekeown"} 896 | 897 | pygame.mixer.music.load(f"audiobooks\\{audiobook_name}.mp3") 898 | pygame.mixer.music.play() 899 | self.pause.configure(state="normal", image=self.pause_img) 900 | self.audiobooks_data = MP3(f"audiobooks\\{audiobook_name}.mp3") 901 | self.audiobooks_length = int(self.audiobooks_data.info.length) 902 | self.music_duration_label.configure(text=time.strftime('%M:%S', time.gmtime(self.audiobooks_length))) 903 | self.scale_update2() 904 | self.insertSongImage2(audiobook_name) 905 | 906 | author_name = author[audiobook_name] 907 | 908 | if len(author_name) > 16: 909 | self.play_control_frame.pack_configure(padx=20) 910 | if len(author_name) < 16: 911 | self.play_control_frame.pack_configure(padx=140) 912 | 913 | self.singer_name.configure(text=f"{author[audiobook_name]}") 914 | 915 | def play_music(self, music_name): 916 | self.favourite.pack(side=RIGHT, padx=80) 917 | if self.music_playing != music_name: 918 | pygame.mixer.music.load(f"songs\\{music_name}") 919 | pygame.mixer.music.play() 920 | self.pause.configure(state="normal", image=self.pause_img) 921 | self.music_data = MP3(f"songs\\{music_name}") 922 | self.music_length = int(self.music_data.info.length) 923 | self.music_duration_label.configure(text=time.strftime('%M:%S', time.gmtime(self.music_length))) 924 | self.scale_update() 925 | self.insertSongImage(music_name) 926 | self.configure_music(music_name) 927 | self.previous_song.append(music_name) 928 | artist_name = self.get_music_info(f"songs\\{music_name}")["artist"] 929 | self.singer_name.configure(text=artist_name) 930 | if len(artist_name) > 16: # type: ignore 931 | self.play_control_frame.pack_configure(padx=20) 932 | if len(artist_name) < 16: # type: ignore 933 | self.play_control_frame.pack_configure(padx=140) 934 | 935 | self.music_playing = music_name 936 | 937 | def configure_music(self, music_name): 938 | if music_name in self.favourites: 939 | self.favourite.configure(image=self.favourite_img2, command=self.remove_favourite) 940 | else: 941 | self.favourite.configure(image=self.favourite_img, command=self.add_favourite) 942 | 943 | def insertSongImage(self, image): 944 | music_name = image.lower().replace(" ", "_") 945 | music_name = music_name.split(".") 946 | music_name[1] = ".png" 947 | music_name = str(music_name[0] + music_name[1]) 948 | self.image = ct.CTkImage(Image.open(os.path.join(song_image_path, f"{music_name}")), size= (45, 45)) 949 | self.image_song_label.configure(image=self.image) 950 | 951 | def insertSongImage2(self, image): 952 | audiobook_name = image.lower() 953 | audiobook_name = audiobook_name.replace(" ", "_") 954 | audiobook_name = f"{audiobook_name}.png" 955 | self.image = ct.CTkImage(Image.open(os.path.join(audiobooks_image_path, f"{audiobook_name}")), size= (45, 45)) 956 | self.image_song_label.configure(image=self.image) 957 | 958 | def scale_update(self): 959 | try: 960 | self.root.after_cancel(self.updater2) 961 | self.updater2 = None 962 | except: 963 | pass 964 | self.slider.configure(to=self.music_data.info.length) 965 | current_position = pygame.mixer.music.get_pos() 966 | self.position = int(current_position / 1000) 967 | self.slider.set(int(current_position / 1000)) 968 | self.time_elapsed_label.configure(text=time.strftime('%M:%S', time.gmtime(self.slider.get()))) 969 | self.updater = self.root.after(1000, self.scale_update) 970 | 971 | def scale_update2(self): 972 | try: 973 | self.root.after_cancel(self.updater) 974 | self.updater = None 975 | except: 976 | pass 977 | self.slider.configure(to=self.audiobooks_data.info.length) 978 | current_position = pygame.mixer.music.get_pos() 979 | self.position = int(current_position / 1000) 980 | self.slider.set(int(current_position / 1000)) 981 | self.time_elapsed_label.configure(text=time.strftime('%M:%S', time.gmtime(self.slider.get()))) 982 | self.updater2 = self.root.after(1000, self.scale_update2) 983 | 984 | def stop_music(self): 985 | if pygame.mixer.music.get_busy(): 986 | pygame.mixer.music.pause() 987 | self.pause.configure(image=self.stop_img, command=self.resume_music) 988 | else: 989 | pass 990 | 991 | def resume_music(self): 992 | pygame.mixer.music.unpause() 993 | self.pause.configure(image=self.pause_img, command=self.stop_music) 994 | 995 | def select_frame_name(self, name): 996 | self.search.configure(fg_color="#444" if name == "search" else "transparent") 997 | self.home.configure(fg_color="#444" if name == "home" else "transparent") 998 | self.artists.configure(fg_color="#444" if name == "artists" else "transparent") 999 | self.trending.configure(fg_color="#444" if name == "trending" else "transparent") 1000 | self.audiobooks.configure(fg_color="#444" if name == "audiobooks" else "transparent") 1001 | self.settings.configure(fg_color="#444" if name == "settings" else "transparent") 1002 | self.favourites_btn.configure(fg_color="#444" if name == "favourites" else "transparent") 1003 | 1004 | if name == "search": 1005 | self.search_frame.pack(fill=BOTH, expand=True) 1006 | else: 1007 | self.search_frame.pack_forget() 1008 | if name == "home": 1009 | self.home_frame.pack(fill=BOTH, expand=True) 1010 | else: 1011 | self.home_frame.pack_forget() 1012 | if name == "artists": 1013 | self.discover_frame.pack(fill=BOTH, expand=True) 1014 | else: 1015 | self.discover_frame.pack_forget() 1016 | if name == "trending": 1017 | self.popular_frame.pack(fill=BOTH, expand=True) 1018 | else: 1019 | self.popular_frame.pack_forget() 1020 | if name == "audiobooks": 1021 | self.audiobooks_frame.pack(fill=BOTH, expand=True) 1022 | else: 1023 | self.audiobooks_frame.pack_forget() 1024 | if name == "favourites": 1025 | self.favourites_frame.pack(fill=BOTH, expand=True) 1026 | else: 1027 | self.favourites_frame.pack_forget() 1028 | if name == "settings": 1029 | self.settings_frame.pack(fill=BOTH, expand=True) 1030 | else: 1031 | self.settings_frame.pack_forget() 1032 | 1033 | def add_music(app): 1034 | # Music code here 1035 | app.add_Music(music_name="Let Me Down Slowly", music_image_name="let_me_down_slowly.png", tab="home1") 1036 | app.add_Music(music_name="Raghupathi Raghava Rajaram", music_image_name="raghupathi_raghava_rajaram.png", tab="home1") 1037 | app.add_Music(music_name="Ram Aayenge", music_image_name="ram_aayenge.png", tab="home1") 1038 | app.add_Music(music_name="Tu Jo Mila", music_image_name="tu_jo_mila.png", tab="home1") 1039 | 1040 | app.add_Music(music_name="Faded", music_image_name="faded.png", tab="home2") 1041 | app.add_Music(music_name="See you Again", music_image_name="see_you_again.png", tab="home2") 1042 | app.add_Music(music_name="Hymn For The Weekend", music_image_name="hymn_for_the_weekend.png", tab="home2") 1043 | app.add_Music(music_name="Into Your Arms", music_image_name="into_your_arms.png", tab="home2") 1044 | 1045 | app.add_Music(music_name="Infinity", music_image_name="infinity.png", tab="home3") 1046 | app.add_Music(music_name="Can We Kiss Forever", music_image_name="can_we_kiss_forever.png", tab="home3") 1047 | app.add_Music(music_name="Arcade", music_image_name="arcade.png", tab="home3") 1048 | app.add_Music(music_name="Safari", music_image_name="safari.png", tab="home3") 1049 | 1050 | app.add_Music(music_name="Fearless", music_image_name="fearless.png", tab="home4") 1051 | app.add_Music(music_name="Tum Hi Ho", music_image_name="tum_hi_ho.png", tab="home4") 1052 | app.add_Music(music_name="Khairiyat", music_image_name="Khairiyat.png", tab="home4") 1053 | app.add_Music(music_name="Baaton Ko Teri", music_image_name="baaton_ko_teri.png", tab="home4") 1054 | 1055 | app.add_Music(music_name="Khamoshiyan", music_image_name="khamoshiyan.png", tab="home5") 1056 | app.add_Music(music_name="Tere Sang Yaara", music_image_name="tere_sang_yaara.png", tab="home5") 1057 | app.add_Music(music_name="Chhod Diya", music_image_name="chhod_diya.png", tab="home5") 1058 | app.add_Music(music_name="Phir Mohabbat", music_image_name="phir_mohabbat.png", tab="home5") 1059 | 1060 | # AudioBooks code here 1061 | app.add_audiobooks(audiobook_name="Atomic Habits", audiobook_image_name="atomic_habits.png", tab="audiobooks1") 1062 | app.add_audiobooks(audiobook_name="Digital Minimalism", audiobook_image_name="digital_minimalism.png", tab="audiobooks1") 1063 | app.add_audiobooks(audiobook_name="Rework", audiobook_image_name="rework.png", tab="audiobooks1") 1064 | app.add_audiobooks(audiobook_name="HyperFocus", audiobook_image_name="hyperfocus.png", tab="audiobooks1") 1065 | app.add_audiobooks(audiobook_name="The Richest Man in Babylon", audiobook_image_name="the_richest_man_in_babylon.png", tab="audiobooks1") 1066 | app.add_audiobooks(audiobook_name="Essentialism", audiobook_image_name="essentialism.png", tab="audiobooks2") 1067 | 1068 | if __name__ == "__main__": 1069 | pygame.mixer.init() 1070 | 1071 | root = ct.CTk() 1072 | 1073 | if os.path.exists("data.txt"): 1074 | if os.path.exists("imagename.txt"): 1075 | app = Spotify(root) 1076 | add_music(app) 1077 | else: 1078 | IntroPage(root) 1079 | else: 1080 | IntroPage(root) 1081 | 1082 | cProfile.run("root.mainloop()", sort="time") 1083 | -------------------------------------------------------------------------------- /Spotify.pyw: -------------------------------------------------------------------------------- 1 | import os, cProfile, pygame, time, random, threading 2 | from tkinter import BOTH, LEFT, RIGHT, TOP, BOTTOM, X, Y, CENTER 3 | import customtkinter as ct 4 | from CTkXYFrame import CTkXYFrame 5 | from PIL import Image 6 | from mutagen.mp3 import MP3 7 | from extract_info.extract_artist import get_artist 8 | from ctypes import windll 9 | from CTkMessagebox import CTkMessagebox 10 | from tkinter import Toplevel 11 | 12 | ct.set_default_color_theme("green") 13 | ct.set_appearance_mode("dark") 14 | 15 | class IntroPage: 16 | def __init__(self, root): 17 | self.root = root 18 | self.root.title("Spotfiy - A modern music player built with Python") 19 | self.root.geometry("550x300") 20 | self.root.iconbitmap("images\\spotify.ico") 21 | self.root.overrideredirect(True) 22 | 23 | with open("imagename.txt", "w") as f: 24 | f.write("avator.png") 25 | 26 | image_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "images") 27 | spotify_image = ct.CTkImage(Image.open(os.path.join(image_path, "spotify.png")), size=(90, 90)) 28 | 29 | ct.CTkLabel(self.root, text=" Spotify", image=spotify_image, compound=LEFT, font=("Poppins", 60, "bold")).pack(padx=10, pady=120, anchor="center") 30 | 31 | self.text = ct.CTkLabel(self.root, text="Please wait...The First launch of the app may take longer...", font=("IBM Plex Sans", 15)) 32 | self.progressbar = ct.CTkProgressBar(self.root, orientation="horizontal", width=300, mode="determinate", determinate_speed=0.35, 33 | fg_color="white", height=8, progress_color="#1ED765", corner_radius=0) 34 | self.progressbar.pack(side=BOTTOM, fill=X) 35 | self.text.pack(side=BOTTOM, anchor="center") 36 | 37 | self.progressbar.set(0) 38 | self.progressbar.start() 39 | 40 | self.thread = threading.Thread(target=self.loading) 41 | self.thread.start() 42 | self.set_appwindow(self.root) 43 | self.center_window(self.root) 44 | 45 | def loading(self): 46 | time.sleep(3) 47 | self.text.configure(text="") 48 | self.text.configure(text="Please wait.....The First launch of the app may take longer...") 49 | self.progressbar.stop() 50 | self.progressbar.set(100) 51 | self.main() 52 | 53 | def center_window(self, win): 54 | win.update_idletasks() 55 | width = win.winfo_width() 56 | height = win.winfo_height() 57 | x = (win.winfo_screenwidth() // 2) - (width // 2) 58 | y = (win.winfo_screenheight() // 2) - (height // 2) 59 | win.geometry('{}x{}+{}+{}'.format(width, height, x, y)) 60 | 61 | def set_appwindow(self, mainWindow): 62 | GWL_EXSTYLE = -20 63 | WS_EX_APPWINDOW = 0x00040000 64 | WS_EX_TOOLWINDOW = 0x00000080 65 | hwnd = windll.user32.GetParent(mainWindow.winfo_id()) 66 | stylew = windll.user32.GetWindowLongW(hwnd, GWL_EXSTYLE) 67 | stylew = stylew & ~WS_EX_TOOLWINDOW 68 | stylew = stylew | WS_EX_APPWINDOW 69 | res = windll.user32.SetWindowLongW(hwnd, GWL_EXSTYLE, stylew) 70 | mainWindow.wm_withdraw() 71 | mainWindow.after(10, lambda: mainWindow.wm_deiconify()) 72 | 73 | def main(self): 74 | for widget in self.root.winfo_children(): 75 | widget.destroy() 76 | 77 | LoginPage(root) 78 | 79 | class LoginPage: 80 | def __init__(self, root): 81 | self.root = root 82 | self.root.overrideredirect(False) 83 | self.root.title("Spotify - Login to play songs for free") 84 | self.root.geometry("1000x600+200+40") 85 | self.root.configure(fg_color="#1b1717") 86 | self.root.resizable(False, False) 87 | 88 | Height = 12 89 | Width = 300 90 | icon_size = 35 91 | 92 | image_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "images") 93 | spotify_image = ct.CTkImage(Image.open(os.path.join(image_path, "spotify2.png")), size=(100, 75)) 94 | email_image = ct.CTkImage(Image.open(os.path.join(image_path, "mail.png")), size=(icon_size, icon_size)) 95 | password_image = ct.CTkImage(Image.open(os.path.join(image_path, "lock.png")), size=(icon_size, icon_size)) 96 | 97 | self.loginframe = ct.CTkFrame(self.root, fg_color="#111", corner_radius=15) 98 | 99 | ct.CTkLabel(self.loginframe, text="Spotify", image=spotify_image, compound=LEFT, font=("monospace", 40, "bold"), text_color="white").pack(pady=30, side=TOP, anchor="nw", padx=100) 100 | 101 | ct.CTkLabel(self.loginframe, text="Music for everyone", font=("monospace", 30, "bold"), text_color="white").pack(pady=15) 102 | 103 | self.username_frame = ct.CTkFrame(self.loginframe, height=0, width=0, fg_color="#333") 104 | ct.CTkLabel(self.username_frame, text="", image=email_image, fg_color="transparent", corner_radius=0).pack(side=LEFT, padx=10) 105 | self.usernameInput = ct.CTkEntry(self.username_frame, placeholder_text="Email or username", font=("monospace", 20, "bold"), 106 | height=Height, width=Width, text_color="#f3f3f3", fg_color="transparent", border_width=0) 107 | self.usernameInput.pack(side=LEFT, ipady=15) 108 | self.username_frame.pack(pady=10, ipadx=10, ipady=2) 109 | 110 | self.password_frame = ct.CTkFrame(self.loginframe, height=0, width=0, fg_color="#333") 111 | ct.CTkLabel(self.password_frame, text="", image=password_image, fg_color="transparent", corner_radius=0).pack(side=LEFT, padx=10) 112 | self.passwordInput = ct.CTkEntry(self.password_frame, placeholder_text="Password", font=("monospace", 20, "bold"), 113 | height=Height, width=Width, text_color="white", fg_color="transparent", border_width=0, show="*") 114 | self.passwordInput.pack(side=LEFT, ipady=15) 115 | self.password_frame.pack(pady=5, ipadx=10, ipady=2) 116 | 117 | self.loginBtn = ct.CTkButton(self.loginframe, text="LOG IN", text_color="black", font=("monospace", 20, "bold"), fg_color="white", corner_radius=10, 118 | hover_color="#dcdada", command=self.login) 119 | self.loginBtn.pack(side=TOP, fill=X, padx=55, pady=10, ipady=10) 120 | 121 | self.loginframe.pack(side=TOP, fill=BOTH, expand=True, pady=40, padx=260) 122 | 123 | progressbar_frame = ct.CTkFrame(self.loginframe, height=0, width=0, fg_color="transparent") 124 | self.progressbar = ct.CTkProgressBar(self.loginframe, orientation="horizontal", mode="determinate", determinate_speed=0.6, 125 | fg_color="white", height=5, progress_color="#1ED765", corner_radius=0, ) 126 | self.progressbar.set(0) 127 | self.progressbar.pack(side=BOTTOM, fill=X) 128 | progressbar_frame.pack(side=BOTTOM, fill=X) 129 | 130 | self.thread = threading.Thread(target=self.loading) 131 | 132 | def login(self): 133 | username = self.usernameInput.get() 134 | password = self.passwordInput.get() 135 | 136 | if len(username) == 0 or len(password) == 0: 137 | CTkMessagebox(title="Error", message=" Username or Password can't be empty ", icon="cancel", font=("monospace", 15, "bold"), text_color="white", wraplength=600) 138 | else: 139 | if len(password) > 8: 140 | CTkMessagebox(title="Error", message=" Password should not be more than 8 digits", icon="cancel", font=("monospace", 15, "bold"), text_color="white", wraplength=600) 141 | else: 142 | with open("data.txt", "w") as f: 143 | user_name = username.split("@")[0] 144 | data = {"name" : user_name, "password" : password, "email" : f"{user_name}@spotify.com"} 145 | f.write(str(data)) 146 | 147 | self.progressbar.start() 148 | self.thread.start() 149 | 150 | def loading(self): 151 | time.sleep(1.5) 152 | self.progressbar.stop() 153 | self.progressbar.set(100) 154 | 155 | for widget in self.root.winfo_children(): 156 | widget.destroy() 157 | 158 | app = Spotify(self.root) 159 | add_music(app) 160 | 161 | class AvatorPageTopLevel: 162 | def __init__(self, master, on_close_callback=False): 163 | self.on_close_callback = on_close_callback 164 | self.profile_window = ct.CTkToplevel(master, fg_color="black") 165 | self.profile_window.iconbitmap("images\\spotify.ico") 166 | self.profile_window.title("Select your avator for profile") 167 | 168 | toplevel_width = 750 169 | toplevel_height = 450 170 | x = (master.winfo_screenwidth() // 2) - (toplevel_width // 2) 171 | y = (master.winfo_screenheight() // 2) - (toplevel_height // 2) 172 | self.profile_window.geometry(f"{toplevel_width}x{toplevel_height}+{x}+{y}") 173 | 174 | self.profile_window.resizable(False, False) 175 | self.profile_window.attributes("-topmost", True) 176 | self.profile_window.grab_set() 177 | 178 | self.avator_images = [] 179 | image_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "avator") 180 | 181 | for i in range(1, 17): 182 | self.avator_images.append(ct.CTkImage(Image.open(os.path.join(image_path, f"avator{i}.png")), size=(200, 200))) 183 | 184 | self.current_avator_index = 0 185 | 186 | avator_frame = ct.CTkFrame(self.profile_window, fg_color="transparent") 187 | ct.CTkLabel(avator_frame, text="Select your Avator", font=("Canbera", 45, "bold"), text_color="white").pack(side=TOP, fill=X, anchor="nw", padx=0, pady=10) 188 | 189 | avator1 = self.avator_images[0] 190 | avator2 = self.avator_images[1] 191 | avator3 = self.avator_images[2] 192 | avator4 = self.avator_images[3] 193 | avator5 = self.avator_images[4] 194 | avator6 = self.avator_images[5] 195 | avator7 = self.avator_images[6] 196 | 197 | icon_right = ct.CTkImage(Image.open(os.path.join(image_path, "right.png")), size=(50, 50)) 198 | icon_left = ct.CTkImage(Image.open(os.path.join(image_path, "left.png")), size=(50, 50)) 199 | 200 | self.left_button = ct.CTkButton(avator_frame, text="", image=icon_left, fg_color="transparent", width=0, hover_color="#222", command=self.change_avator_left) 201 | self.left_button.pack(side=LEFT, padx=5) 202 | self.avator = ct.CTkButton(avator_frame, text="", image=avator1, width=1, height=1, fg_color="transparent", hover_color="#000", corner_radius=50) 203 | self.avator.pack(side=LEFT, anchor="center", padx=120) 204 | self.right_button = ct.CTkButton(avator_frame, text="", image=icon_right, fg_color="transparent", width=0, hover_color="#222", command=self.change_avator_right) 205 | self.right_button.pack(side=RIGHT, padx=5) 206 | 207 | self.progressbar = ct.CTkProgressBar(self.profile_window, orientation="horizontal", width=300, mode="determinate", determinate_speed=0.9, fg_color="#333", height=5, progress_color="#1ED765", corner_radius=0) 208 | self.progressbar.pack(side=BOTTOM, fill=X) 209 | self.progressbar.set(0) 210 | 211 | self.select = ct.CTkButton(self.profile_window, text="Select", font=("monospace", 23, "normal"), height=50, width=150, command=self.select_avator) 212 | self.select.pack(side=BOTTOM, anchor="center", pady=20) 213 | 214 | avator_frame.pack(side=TOP, fill=X, padx=80, pady=30, ipadx=50, ipady=20) 215 | 216 | self.profile_window.mainloop() 217 | 218 | def select_avator(self): 219 | self.avator.configure(fg_color="#222", hover_color="#222") 220 | image = f"avator{self.current_avator_index+1}.png" 221 | with open("imagename.txt", "w") as f: 222 | f.write(image) 223 | self.select.configure(text=" Processing...", state="disabled") 224 | self.progressbar.start() 225 | self.profile_window.after(1000, self.loading) 226 | 227 | def loading(self): 228 | time.sleep(0.5) 229 | self.profile_window.after(0, self.close_window) 230 | 231 | def close_window(self): 232 | self.profile_window.destroy() 233 | if self.on_close_callback(): 234 | self.on_close_callback() 235 | 236 | def change_avator_right(self): 237 | self.avator.configure(fg_color="transparent", hover_color="black") 238 | self.current_avator_index = (self.current_avator_index + 1) % len(self.avator_images) 239 | self.avator.configure(image=self.avator_images[self.current_avator_index]) 240 | 241 | def change_avator_left(self): 242 | self.avator.configure(fg_color="transparent", hover_color="black") 243 | self.current_avator_index = (self.current_avator_index - 1) % len(self.avator_images) 244 | self.avator.configure(image=self.avator_images[self.current_avator_index]) 245 | 246 | class Spotify: 247 | def __init__(self, root): 248 | self.root = root 249 | self.root.title("Spotify") 250 | self.root.geometry("1300x700") 251 | self.root.minsize(1300, 700) 252 | self.bg_color = "#202124" 253 | self.root.configure(fg_color=self.bg_color) 254 | self.root.resizable(True, True) 255 | self.root.iconbitmap("images\\spotify.ico") 256 | # pywinstyles.apply_style(self, style="acrylic") 257 | 258 | # Load images from the images folder 259 | image_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "images") 260 | self.spotify_img = ct.CTkImage(Image.open(os.path.join(image_path, "spotify.png")), size=(50, 50)) 261 | self.home_img = ct.CTkImage(Image.open(os.path.join(image_path, "home.png")), size=(25, 25)) 262 | self.discover_img = ct.CTkImage(Image.open(os.path.join(image_path, "song.png")), size=(25, 25)) 263 | self.rise_img = ct.CTkImage(Image.open(os.path.join(image_path, "rise.png")), size=(25, 20)) 264 | self.rise_img2 = ct.CTkImage(Image.open(os.path.join(image_path, "search2.png")), size=(20, 20)) 265 | self.audiobooks_img = ct.CTkImage(Image.open(os.path.join(image_path, "headphones.png")), size=(25, 25)) 266 | self.audiobooks_img2 = ct.CTkImage(Image.open(os.path.join(image_path, "bookopen.png")), size=(45, 45)) 267 | self.settings_img = ct.CTkImage(Image.open(os.path.join(image_path, "settings.png")), size=(25, 25)) 268 | self.search_img = ct.CTkImage(Image.open(os.path.join(image_path, "search.png")), size=(30, 30)) 269 | self.add_img = ct.CTkImage(Image.open(os.path.join(image_path, "plus.png")), size=(33, 33)) 270 | self.delete_img = ct.CTkImage(Image.open(os.path.join(image_path, "delete2.png")), size=(28, 28)) 271 | self.edit_img = ct.CTkImage(Image.open(os.path.join(image_path, "edit.png")), size=(28, 28)) 272 | self.favourite_img3 = ct.CTkImage(Image.open(os.path.join(image_path, "star.png")), size=(28, 28)) 273 | self.eyes_icon_open = ct.CTkImage(Image.open(os.path.join(image_path, "eyes_open.png")), size=(20, 20)) 274 | self.eyes_icon_closed = ct.CTkImage(Image.open(os.path.join(image_path, "eyes_closed.png")), size=(20, 20)) 275 | 276 | self.image_path_avatar = os.path.join(os.path.dirname(os.path.realpath(__file__)), "avator") 277 | with open("imagename.txt", "r") as f: 278 | profile_image = f.read() 279 | self.profile_img = ct.CTkImage(Image.open(os.path.join(self.image_path_avatar, profile_image)), size=(35, 35)) # avator profile 280 | self.avator_image = ct.CTkImage(Image.open(os.path.join(self.image_path_avatar, profile_image)), size=(155, 155)) # avator profile 281 | 282 | self.nav_frame = ct.CTkFrame(self.root, fg_color="#141517") 283 | 284 | self.spotify_label = ct.CTkLabel(self.nav_frame, text=" Spotify ", text_color="white", image=self.spotify_img, compound=LEFT, 285 | font=("Poppins", 30)) 286 | self.spotify_label.pack(side=TOP, padx=10, pady=5) 287 | 288 | ct.CTkLabel(self.nav_frame, text="").pack(pady=5) 289 | 290 | self.search = ct.CTkButton(self.nav_frame, text="Search", width=50, height=40, fg_color="transparent", hover_color="#444", 291 | corner_radius=10, image=self.search_img, font=("Montserrat", 20), text_color="white", anchor="w", command=lambda: self.select_frame_name("search")) 292 | self.search.pack(side=TOP, pady=5, ipady=5, padx=5, fill=X) 293 | 294 | ct.CTkButton(self.nav_frame, text="", fg_color="transparent", hover_color="#141517", text_color="white").pack(side=TOP, pady=10, fill=X) 295 | 296 | self.home = ct.CTkButton(self.nav_frame, text="Home", width=50, height=40, fg_color="transparent", hover_color="#444", 297 | corner_radius=10, image=self.home_img, font=("Montserrat", 20), text_color="white", anchor="w", command=lambda: self.select_frame_name("home")) 298 | self.home.pack(side=TOP, pady=5, ipady=5, padx=5, fill=X) 299 | 300 | self.artists = ct.CTkButton(self.nav_frame, text="Artists", width=50, height=40, fg_color="transparent", hover_color="#444", 301 | corner_radius=10, image=self.discover_img, font=("Montserrat", 20), text_color="white", anchor="w", command=lambda: self.select_frame_name("artists")) 302 | self.artists.pack(side=TOP, pady=5, ipady=5, padx=5, fill=X) 303 | 304 | self.trending = ct.CTkButton(self.nav_frame, text="Trending", width=50, height=40, fg_color="transparent", hover_color="#444", 305 | corner_radius=10, image=self.rise_img, font=("Montserrat", 20), text_color="white", anchor="w", command=lambda: self.select_frame_name("trending")) 306 | self.trending.pack(side=TOP, pady=5, ipady=5, padx=5, fill=X) 307 | 308 | self.audiobooks = ct.CTkButton(self.nav_frame, text="AudioBooks", width=50, height=40, fg_color="transparent", hover_color="#444", 309 | corner_radius=10, image=self.audiobooks_img, font=("Montserrat", 20), text_color="white", anchor="w", command=lambda: self.select_frame_name("audiobooks")) 310 | self.audiobooks.pack(side=TOP, pady=5, ipady=5, padx=5, fill=X) 311 | 312 | self.favourites_btn = ct.CTkButton(self.nav_frame, text="Favourites", width=50, height=40, fg_color="transparent", hover_color="#444", 313 | corner_radius=10, image=self.favourite_img3, font=("Montserrat", 20), text_color="white", anchor="w", command=lambda: self.select_frame_name("favourites")) 314 | self.favourites_btn.pack(side=TOP, pady=5, ipady=5, padx=5, fill=X) 315 | 316 | self.settings = ct.CTkButton(self.nav_frame, text="Settings", width=50, height=40, fg_color="transparent", hover_color="#444", 317 | corner_radius=10, image=self.settings_img, font=("Montserrat", 20), text_color="white", anchor="w", command=lambda: self.select_frame_name("settings")) 318 | self.settings.pack(side=BOTTOM, pady=10, ipady=5, padx=5, fill=X) 319 | 320 | self.nav_frame.pack(side=LEFT, fill=Y) 321 | 322 | self.main = ct.CTkFrame(self.root, corner_radius=0, fg_color=self.bg_color) 323 | self.main.pack(fill=BOTH, expand=True) 324 | 325 | # Create all the frames for every tab inside the main frame 326 | self.color_home_frame = "#333" 327 | 328 | # Search frame code here ......................... 329 | self.search_frame = ct.CTkFrame(self.main, corner_radius=0, fg_color="#555") 330 | self.search_label = ct.CTkLabel(self.search_frame, text="", image=self.search_img) 331 | 332 | self.search_box = ct.CTkEntry(self.search_frame, font=("IBM Plex Sans", 23), placeholder_text="What do you want to play today ?", placeholder_text_color="#a5a5a5", 333 | corner_radius=10, border_width=0, fg_color=self.bg_color, text_color="white") 334 | self.search_box.pack(side=TOP, fill=X, ipady=15, padx=20, pady=20) 335 | self.search_box.bind("", self.on_button_release) 336 | 337 | self.like_that_entry = ct.CTkEntry(self.search_frame, width=0, height=0, fg_color="#555", text_color="#555", bg_color="#555", border_width=0) 338 | self.like_that_entry.pack(side=BOTTOM, fill=X) 339 | self.search_frame.bind("", lambda event: self.like_that_entry.focus()) 340 | 341 | self.all_songs_name = ['Arcade', 'Can We Kiss Forever', 'Faded', 342 | 'Fearless', 'Hymn For The Weekend', 'Infinity', 'Into Your Arms', 'Khairiyat', 343 | 'Let Me Down Slowly', 'Phir Mohabbat', 'Raghupathi Raghava Rajaram', 344 | 'Ram Aayenge', 'Safari', 'See You Again','Tere Sang Yaara', 345 | 'Tu Jo Mila', 'Tum Hi Ho', 'Chhod Diya'] 346 | 347 | self.searching_frame = ct.CTkFrame(self.search_frame, fg_color="#333") 348 | self.searching_frame.pack(side=TOP, fill=X, padx=20, pady=10) 349 | 350 | #---------------------------------------------------------------------------------------------------- 351 | 352 | self.home_frame = CTkXYFrame(self.main, corner_radius=0, fg_color=self.color_home_frame) 353 | 354 | self.home_label = ct.CTkLabel(self.home_frame, text="Home", font=("Poppins", 50), text_color="white") 355 | self.home_label.pack(anchor="nw", side=TOP, padx=20) 356 | 357 | self.discover_frame = ct.CTkFrame(self.main, corner_radius=0, fg_color="#1f1e42") 358 | self.popular_frame = ct.CTkFrame(self.main, corner_radius=0, fg_color=self.color_home_frame) 359 | self.audiobooks_frame = ct.CTkFrame(self.main, corner_radius=0, fg_color=self.color_home_frame) 360 | self.settings_frame = ct.CTkFrame(self.main, corner_radius=0, fg_color=self.color_home_frame) 361 | self.favourites_frame = ct.CTkFrame(self.main, corner_radius=0, fg_color=self.color_home_frame) 362 | 363 | ##################### ---------- Artists code ---------------- ################################### 364 | 365 | self.artist_frame = ct.CTkScrollableFrame(self.discover_frame, fg_color="transparent") 366 | singer_image_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "singersImage") 367 | ariijt_image = ct.CTkImage(Image.open(os.path.join(singer_image_path, "arijit_singh.png")), size=(250, 250)) 368 | gayathri_image = ct.CTkImage(Image.open(os.path.join(singer_image_path, "g_gayathri_devi.png")), size=(250, 250)) 369 | kk_image = ct.CTkImage(Image.open(os.path.join(singer_image_path, "kk.png")), size=(250, 250)) 370 | atif_alsam_image = ct.CTkImage(Image.open(os.path.join(singer_image_path, "atif_aslam.png")), size=(250, 250)) 371 | alisha_chinai_image = ct.CTkImage(Image.open(os.path.join(singer_image_path, "alisha_chinai.png")), size=(250, 250)) 372 | sachet_tandon_image = ct.CTkImage(Image.open(os.path.join(singer_image_path, "sachet_tandon.png")), size=(250, 250)) 373 | pamphara_thakur_image = ct.CTkImage(Image.open(os.path.join(singer_image_path, "pamphara_thakur.png")), size=(250, 250)) 374 | swati_mishra_image = ct.CTkImage(Image.open(os.path.join(singer_image_path, "swati_mishra.png")), size=(250, 250)) 375 | alan_walker_image = ct.CTkImage(Image.open(os.path.join(singer_image_path, "alan_walker.png")), size=(250, 250)) 376 | alec_benjamin_image = ct.CTkImage(Image.open(os.path.join(singer_image_path, "alec_benjamin.png")), size=(250, 250)) 377 | duncan_laurence_image = ct.CTkImage(Image.open(os.path.join(singer_image_path, "duncan_laurence.png")), size=(250, 250)) 378 | kina_image = ct.CTkImage(Image.open(os.path.join(singer_image_path, "kina.png")), size=(250, 250)) 379 | # uma_mohan_image = ct.CTkImage(Image.open(os.path.join(singer_image_path, "uma_mohan.png")), size=(250, 250)) 380 | 381 | ct.CTkLabel(self.discover_frame, text="Artists", font=("Heleventica", 55, "bold")).pack(side=TOP, anchor="ne", fill=X, pady=5) 382 | 383 | row_1 = ct.CTkFrame(self.artist_frame, fg_color="transparent") 384 | arijit_singh = ct.CTkLabel(row_1, text="Arijit Singh", font=("IBM Plex Sans", 20, "bold"), image=ariijt_image, compound=TOP) 385 | arijit_singh.pack(side=LEFT, padx=25) 386 | g_gayahatri = ct.CTkLabel(row_1, text="G. Gayathri Devi", font=("IBM Plex Sans", 20, "bold"), image=gayathri_image, compound=TOP) 387 | g_gayahatri.pack(side=LEFT, padx=25) 388 | kk = ct.CTkLabel(row_1, text="Krishnakumar Kunnath", font=("IBM Plex Sans", 20, "bold"), image=kk_image, compound=TOP) 389 | kk.pack(side=LEFT, padx=25) 390 | atif_alsam = ct.CTkLabel(row_1, text="Atif Aslam", font=("IBM Plex Sans", 20, "bold"), image=atif_alsam_image, compound=TOP) 391 | atif_alsam.pack(side=LEFT, padx=25) 392 | row_1.pack(fill=X, side=TOP) 393 | 394 | row_2 = ct.CTkFrame(self.artist_frame, fg_color="transparent") 395 | alisha_chinai = ct.CTkLabel(row_2, text="Alisha Chinai", font=("IBM Plex Sans", 20, "bold"), image=alisha_chinai_image, compound=TOP) 396 | alisha_chinai.pack(side=LEFT, padx=25) 397 | sachet_tandon = ct.CTkLabel(row_2, text="Sachet Tandon", font=("IBM Plex Sans", 20, "bold"), image=sachet_tandon_image, compound=TOP) 398 | sachet_tandon.pack(side=LEFT, padx=25) 399 | pamphara_thakur = ct.CTkLabel(row_2, text="Parampara Thakur", font=("IBM Plex Sans", 20, "bold"), image=pamphara_thakur_image, compound=TOP) 400 | pamphara_thakur.pack(side=LEFT, padx=25) 401 | swati_mishra = ct.CTkLabel(row_2, text="Swati Mishra", font=("IBM Plex Sans", 20, "bold"), image=swati_mishra_image, compound=TOP) 402 | swati_mishra.pack(side=LEFT, padx=25) 403 | 404 | row_2.pack(fill=X, side=TOP, pady=20) 405 | 406 | row_3 = ct.CTkFrame(self.artist_frame, fg_color="transparent") 407 | 408 | alan_walker = ct.CTkLabel(row_3, text="Alan Walker", font=("IBM Plex Sans", 20, "bold"), image=alan_walker_image, compound=TOP) 409 | alan_walker.pack(side=LEFT, padx=25) 410 | alec_benjemin = ct.CTkLabel(row_3, text="Alec Benjamin", font=("IBM Plex Sans", 20, "bold"), image=alec_benjamin_image, compound=TOP) 411 | alec_benjemin.pack(side=LEFT, padx=25) 412 | duncan_laurence = ct.CTkLabel(row_3, text="Duncan Laurence", font=("IBM Plex Sans", 20, "bold"), image=duncan_laurence_image, compound=TOP) 413 | duncan_laurence.pack(side=LEFT, padx=25) 414 | kina = ct.CTkLabel(row_3, text="Kina Cosper", font=("IBM Plex Sans", 20, "bold"), image=kina_image, compound=TOP) 415 | kina.pack(side=LEFT, padx=25) 416 | 417 | row_3.pack(side=TOP, fill=X) 418 | 419 | self.artist_frame.pack(side=TOP, fill=BOTH, expand=True, padx=20, pady=40) 420 | 421 | 422 | # settings frame code ################################## 423 | 424 | self.profile_frame = ct.CTkFrame(self.settings_frame, fg_color=self.bg_color) 425 | self.profile_button = ct.CTkButton(self.profile_frame, text="", width=0, corner_radius=0, fg_color=self.bg_color, hover_color="#333", image=self.profile_img, command=self.changeProfilePhoto) 426 | self.profile_button.pack(side=RIGHT) 427 | 428 | self.username = ct.CTkLabel(self.profile_frame, text="Username", font=("IBM Plex Sans", 25, "bold")) 429 | self.username.pack(anchor="center", side=LEFT, padx=15) 430 | 431 | self.profile_frame.pack(side=TOP, fill=X, ipady=10, padx=5, pady=2, ipadx=10) 432 | 433 | # settings control frame all the settings 434 | self.settings_control_frame = ct.CTkFrame(self.settings_frame, fg_color=self.bg_color) 435 | 436 | ct.CTkLabel(self.settings_control_frame, text="Settings", font=("IBM Plex Sans", 40, "bold")).pack(side=TOP, anchor="nw", padx=20, pady=20) 437 | 438 | # auto update frame 439 | self.update_frame = ct.CTkFrame(self.settings_control_frame) 440 | self.update_btn = ct.CTkSwitch(self.update_frame, text="", switch_height=30, switch_width=60, font=("Poppins", 40, "bold")) 441 | upadte_text = ct.CTkLabel(self.update_frame, text="Auto-Update", font=("IBM Plex Sans", 25, "bold")) 442 | upadte_text.pack(side=LEFT, padx=20) 443 | self.update_btn.pack(side=RIGHT, padx=2) 444 | self.update_frame.pack(side=TOP, fill=X, padx=15, ipady=10) 445 | self.update_frame.bind("", self.toggle_update) 446 | 447 | # account frame 448 | self.account_frame = ct.CTkFrame(self.settings_control_frame) 449 | 450 | with open("data.txt", "r") as f: 451 | data = f.readline().strip() 452 | 453 | try: data_dict = eval(data) 454 | except Exception: data_dict = {} 455 | 456 | email_value = data_dict.get("email") 457 | password_value = data_dict.get("password") 458 | 459 | name = data_dict.get("name") 460 | self.username.configure(text=name) 461 | 462 | self.email = data_dict.get("email") if email_value else "username@spotify.com" 463 | self.password = data_dict.get("password") if password_value else "12345678" 464 | 465 | self.account_details_frame = ct.CTkFrame(self.account_frame, fg_color="transparent") 466 | ct.CTkLabel(self.account_details_frame, text="Account", font=("Poppins", 30, "bold")).pack(side=TOP, anchor="nw", padx=10) 467 | 468 | details_frame = ct.CTkFrame(self.account_details_frame, fg_color="transparent") 469 | 470 | self.email_label = ct.CTkLabel(details_frame, text=f"Email-ID : {self.email}", font=("IBM Plex Sans", 20, "bold")) 471 | 472 | password_frame = ct.CTkFrame(details_frame, fg_color="transparent") 473 | self.password_label = ct.CTkLabel(password_frame, text=f"Password : ", font=("IBM Plex Sans", 20, "bold")) 474 | self.password_input = ct.CTkLabel(password_frame, font=("consolas", 20, "bold"), text="********") 475 | self.icon_eyes = ct.CTkButton(password_frame, text="", image=self.eyes_icon_closed, width=0, font=("consolas", 100), fg_color="transparent", hover_color=self.bg_color, command=self.show_password) 476 | self.password_label.pack(side=LEFT) 477 | self.password_input.pack(side=LEFT) 478 | self.icon_eyes.pack(side=LEFT, padx=5) 479 | 480 | self.email_label.pack(side=TOP, anchor="nw") 481 | password_frame.pack(side=TOP, anchor="nw") 482 | 483 | details_frame.pack(side=LEFT, pady=10, padx=10) 484 | self.account_details_frame.pack(side=LEFT, fill=BOTH, expand=True, pady=10, padx=10) 485 | 486 | self.photo_frame = ct.CTkLabel(self.account_frame, text="", image=self.avator_image, fg_color="transparent") 487 | self.photo_frame.pack(side=RIGHT, padx=40, fill=BOTH, ipadx=10, pady=10) 488 | 489 | self.delete_account = ct.CTkButton(details_frame, text="Delete Account", font=("Poppins", 20, "bold"), fg_color="#e15455", hover_color="#f44344", corner_radius=10, bg_color="transparent", command=self.deleteAccount) 490 | self.delete_account.pack(side=TOP, anchor="nw", ipady=7, pady=5) 491 | 492 | self.account_frame.pack(side=TOP, fill=X, padx=15, ipady=10, pady=10) 493 | 494 | # about frame 495 | self.about_frame = ct.CTkFrame(self.settings_control_frame) 496 | 497 | ct.CTkLabel(self.about_frame, text="About", font=("IBM Plex Sans", 40, "bold")).pack(side=TOP, anchor="nw", padx=20, pady=20) 498 | ct.CTkLabel(self.about_frame, text="About : © 2024 Spotify Limited. All rights reserved", font=("consolas", 20, "bold")).pack(side=TOP, anchor="nw", padx=20) 499 | ct.CTkLabel(self.about_frame, text="Version : 1.1", font=("consolas", 20, "bold")).pack(side=TOP, anchor="nw", padx=20) 500 | ct.CTkLabel(self.about_frame, text="Developer : Sarthak Singh", font=("consolas", 20, "bold")).pack(side=TOP, anchor="nw", padx=20) 501 | 502 | self.about_frame.pack(side=TOP, fill=BOTH, padx=15, pady=5, ipady=20) 503 | 504 | self.settings_control_frame.pack(side=TOP, fill=BOTH, expand=True, padx=5, pady=10) 505 | 506 | self.music_playing = None 507 | self.frames = {} # Dictionary to store frames for each tab 508 | self.frames2 = {} # Dictionary to store frames for each tab 509 | # control song frame 510 | 511 | # global stop_img, pause_img 512 | song_image_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "images") 513 | self.pause_img = ct.CTkImage(Image.open(os.path.join(song_image_path, "pause.png")), size= (35, 35)) 514 | self.stop_img = ct.CTkImage(Image.open(os.path.join(song_image_path, "play.png")), size= (35, 35)) 515 | self.skip_forward_img = ct.CTkImage(Image.open(os.path.join(song_image_path, "skip-forward.png")), size= (35, 35)) 516 | self.skip_backward_img = ct.CTkImage(Image.open(os.path.join(song_image_path, "skip-back.png")), size= (35, 35)) 517 | self.loop_img = ct.CTkImage(Image.open(os.path.join(image_path, "loop.png")), size=(36, 36)) 518 | self.shuffle_img = ct.CTkImage(Image.open(os.path.join(image_path, "shuffle.png")), size=(28, 28)) 519 | self.favourite_img = ct.CTkImage(Image.open(os.path.join(image_path, "myHeart.png")), size=(35, 35)) 520 | self.favourite_img2 = ct.CTkImage(Image.open(os.path.join(image_path, "myHeart2.png")), size=(35, 35)) 521 | song_image_path2 = os.path.join(os.path.dirname(os.path.realpath(__file__)), "songs_images") 522 | self.imgPlaylistFavourites = ct.CTkImage(Image.open(os.path.join(song_image_path2, "dark.png")), size=(250, 220)) 523 | 524 | self.control_frame = ct.CTkFrame(self.root, corner_radius=10, fg_color="transparent") 525 | 526 | self.image_song_label = ct.CTkLabel(self.control_frame, text="", fg_color="#555", height=54, width=54, corner_radius=5) 527 | self.image_song_label.pack(side=LEFT, padx=10) 528 | 529 | self.slide_time_frame = ct.CTkFrame(self.control_frame, fg_color="transparent") 530 | 531 | self.time_elapsed_label = ct.CTkLabel(self.slide_time_frame, text="00:00", font=("Poppins", 20)) 532 | self.time_elapsed_label.pack(side=LEFT, padx=10) 533 | 534 | self.music_duration_label = ct.CTkLabel(self.slide_time_frame, text="00:00", font=("Poppins", 20)) 535 | self.music_duration_label.pack(side=RIGHT, padx=10) 536 | 537 | self.slider = ct.CTkSlider(self.slide_time_frame, height=20, fg_color="#4b5d4b", progress_color="#106A43", bg_color="transparent", 538 | command=lambda event: self.slide_song(), from_=0, to=100) 539 | self.slider.pack(fill=X, padx=20) 540 | self.slider.set(0) 541 | 542 | self.slide_time_frame.pack(side=TOP, fill=X) 543 | 544 | ######################################### 545 | 546 | # playlist frame code --------------------- 547 | 548 | self.audiobooks_heading_frame = ct.CTkFrame(self.audiobooks_frame, corner_radius=8, fg_color="#222") 549 | ct.CTkLabel(self.audiobooks_heading_frame, text=" AudioBooks", image=self.audiobooks_img2, font=("Poppins", 30, "bold"), 550 | compound=LEFT, text_color="white").pack(side=LEFT, padx=10, ipady=5, ipadx=10) 551 | self.audiobooks_heading_frame.pack(side=TOP, fill=X, pady=5, padx=10, ipady=10) 552 | 553 | self.audio_frame = ct.CTkScrollableFrame(self.audiobooks_frame) 554 | self.audio_frame.pack(side=TOP, fill=BOTH, expand=True, padx=10, pady=10) 555 | 556 | self.playlist_container = ct.CTkScrollableFrame(self.favourites_frame, fg_color="#202128", corner_radius=10) 557 | self.playlist_container.pack(fill=BOTH, expand=True, padx=5, pady=2) 558 | 559 | self.favourites_playlist = ct.CTkFrame(self.playlist_container, fg_color="#333") 560 | self.favourites_playlist.pack(side=TOP, padx=5, ipady=15, pady=5, fill=X) 561 | 562 | # --------------------- playlist code ................. 563 | ######################################################## 564 | # Play control frame for the control of music 565 | 566 | self.singer_name = ct.CTkLabel(self.control_frame, text="Singer name", font=("IBM Plex Sans", 20, "bold"), text_color="#a5a5a5") 567 | self.singer_name.pack(side=LEFT, padx=10) 568 | 569 | self.play_control_frame = ct.CTkFrame(self.control_frame, fg_color="#212228", width=0) 570 | 571 | self.loop = ct.CTkButton(self.play_control_frame, text="", image=self.loop_img, width=0, fg_color="transparent", command=self.loop_song) 572 | self.loop.pack(side=LEFT, padx=80) 573 | 574 | self.skip_backward = ct.CTkButton(self.play_control_frame, text="", image=self.skip_backward_img, width=0, fg_color="transparent", corner_radius=5, bg_color="transparent", command=self.play_previous_song) 575 | self.skip_backward.pack(side=LEFT) 576 | self.pause = ct.CTkButton(self.play_control_frame, text="", image=self.stop_img, width=0, fg_color="transparent", corner_radius=5, bg_color="transparent", command=self.stop_music, state="disabled") 577 | self.pause.pack(side=LEFT) 578 | self.skip_forward = ct.CTkButton(self.play_control_frame, text="", image=self.skip_forward_img, width=0, fg_color="transparent", corner_radius=5, bg_color="transparent", command=self.play_previous_song) 579 | self.skip_forward.pack(side=LEFT) 580 | 581 | self.favourite = ct.CTkButton(self.play_control_frame, text="", image=self.favourite_img, width=0, fg_color="transparent", 582 | command=self.add_favourite) 583 | self.favourite.pack(side=RIGHT, padx=80) 584 | 585 | self.play_control_frame.pack(side=LEFT, padx=140) 586 | 587 | self.control_frame.pack(side=BOTTOM, fill=X, pady=10) 588 | 589 | self.trends_frame = ct.CTkFrame(self.popular_frame, fg_color="#241d48", bg_color="#241d48") 590 | 591 | ct.CTkLabel(self.trends_frame, text="Popular ", font=("IBM Plex Sans", 40, "bold")).pack(side=TOP, anchor="nw", padx=35, pady=20) 592 | 593 | self.trending_song_frame = ct.CTkFrame(self.trends_frame, fg_color="transparent") 594 | trending_songs = self.generate_random_song(10) 595 | 596 | for i, trends in enumerate(trending_songs): 597 | i+=1 598 | ct.CTkButton(self.trending_song_frame, text=f"{i}. {trends}", font=("Poppins", 21, "normal"), 599 | anchor="w", corner_radius=10, fg_color="#3d375a", hover_color="#464d75", command=lambda song=trends: self.play_music(f"{song}.mp3")).pack(side=TOP, fill=X, ipady=10, padx=10, pady=5) 600 | 601 | self.trending_song_frame.pack(side=TOP, fill=X, padx=20, pady=10) 602 | 603 | self.trends_frame.pack(fill=BOTH, expand=True) 604 | 605 | self.all_songs = [] 606 | self.playlists = [] 607 | self.favourites = [] 608 | self.previous_song = [] 609 | 610 | # Focus the home tab first 611 | self.select_frame_name("home") 612 | 613 | self.position = 0 614 | self.loop = False 615 | self.music_scale = False 616 | 617 | self.root.bind("", self.spacebar_event) 618 | self.open_favourites() 619 | self.updateFavouritePlaylistImage() 620 | 621 | intital_songs = self.generate_random_song(10) 622 | for item in intital_songs: 623 | ct.CTkButton(self.searching_frame, text=f" {item}", width=20, font=("Poppins", 21, "normal"), command=lambda item=item: self.on_button_click(item), 624 | anchor="w", corner_radius=0, fg_color="#333", text_color="#c7c3c3", image=self.rise_img2, hover_color="#444").pack(fill=X, pady=0, ipady=10, padx=5) 625 | 626 | def changeProfilePhoto(self): 627 | def callBack(): 628 | with open("imagename.txt", "r") as f: 629 | image_name = f.read() 630 | profile_img = ct.CTkImage(Image.open(os.path.join(self.image_path_avatar, image_name)), size=((35, 35))) 631 | avator_img = ct.CTkImage(Image.open(os.path.join(self.image_path_avatar, image_name)), size=((155, 155))) 632 | self.profile_button.configure(image=profile_img) 633 | self.photo_frame.configure(image=avator_img) 634 | AvatorPageTopLevel(self.root, on_close_callback=callBack) 635 | 636 | def deleteAccount(self): 637 | if os.path.exists("data.txt"): 638 | msg = CTkMessagebox(title="Delete Account", message=" Are you sure to delete account ? Restart the program to create new account.", icon="question", font=("monospace", 15, "bold"), text_color="white", wraplength=550, option_1="Cancel", option_2="No", option_3="Yes", width=550) 639 | 640 | if msg.get() == "Yes": 641 | msg = CTkMessagebox(title="Delete Account", message="Your account has been deleted", icon="check", option_1="Thanks", cancel_button="circle", cancel_button_color="red") 642 | if msg.get() == "Thanks": 643 | os.remove("data.txt") 644 | self.root.destroy() 645 | else: 646 | pass 647 | 648 | def generate_random_song(self, number): 649 | return random.sample(self.all_songs_name, number) 650 | 651 | def search_filter(self, search_term): 652 | for widget in self.searching_frame.winfo_children(): 653 | widget.destroy() 654 | 655 | if search_term == "": 656 | initial_fruits = self.generate_random_song(8) 657 | for item in initial_fruits: 658 | ct.CTkButton(self.searching_frame, text=f" {item}", width=20, font=("Poppins", 21, "normal"), command=lambda item=item: self.on_button_click(item), 659 | anchor="w", corner_radius=0, fg_color="#333", text_color="#c7c3c3", image=self.rise_img2, hover_color="#444").pack(fill=X, pady=0, ipady=10, padx=5) 660 | else: 661 | filtered_data = [item for item in self.all_songs_name if item.lower().startswith(search_term.lower())] 662 | filtered_data.sort() 663 | for item in filtered_data: 664 | ct.CTkButton(self.searching_frame, text=f" {item}", width=20, font=("Poppins", 21, "normal"), command=lambda item=item: self.on_button_click(item), 665 | anchor="w", corner_radius=0, fg_color="#333", text_color="#c7c3c3", image=self.rise_img2, hover_color="#444").pack(fill=X, pady=0, ipady=10, padx=5) 666 | 667 | def on_button_click(self, item): 668 | music_name = f"{item}.mp3" 669 | self.play_music(music_name) 670 | 671 | def on_button_release(self, event): 672 | search_term = event.widget.get() 673 | self.search_filter(search_term) 674 | 675 | def show_password(self): 676 | self.icon_eyes.configure(image=self.eyes_icon_open, command=self.hide_password) 677 | self.password_input.configure(text=self.password) 678 | 679 | def hide_password(self): 680 | self.icon_eyes.configure(image=self.eyes_icon_closed, command=self.show_password) 681 | self.password_input.configure(text="********") 682 | 683 | def toggle_update(self, event): 684 | self.update_btn.toggle() 685 | 686 | def playPlaylist_song(self): 687 | for music_name in self.favourites: 688 | pygame.mixer.music.load(f"songs\\{music_name}") 689 | pygame.mixer.music.play() 690 | self.insertSongImage(music_name) 691 | self.configure_music(music_name) 692 | self.previous_song.append(music_name) 693 | artist_name = self.get_music_info(f"songs\\{music_name}")["artist"] 694 | self.singer_name.configure(text=artist_name) 695 | 696 | if len(artist_name) > 16: 697 | self.play_control_frame.pack_configure(padx=20) 698 | if len(artist_name) < 16: 699 | self.play_control_frame.pack_configure(padx=140) 700 | 701 | self.favourite.pack(side=RIGHT, padx=80) 702 | 703 | def open_favourites(self): 704 | global playlist_songs_frame, music_name, image_path, title_song 705 | image_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "songs_images") 706 | self.favourites_playlist.pack_forget() 707 | self.playlist_container.pack_forget() 708 | self.favourites_playlist_full = ct.CTkScrollableFrame(self.favourites_frame, fg_color="#222029") 709 | 710 | self.title_frame = ct.CTkFrame(self.favourites_playlist_full) 711 | self.title_frame.pack(side=TOP, fill=X) 712 | 713 | title_song = ct.CTkLabel(self.title_frame, text="", bg_color="transparent", corner_radius=10) 714 | title_song.pack(side=LEFT, pady=10) 715 | 716 | space = ct.CTkLabel(self.title_frame, text="") 717 | space.pack(side=TOP, anchor="nw", pady=20, padx=10) 718 | 719 | title = ct.CTkLabel(self.title_frame, text="Favourites", font=("Poppins", 50, "bold"), text_color="white") 720 | title.pack(side=TOP, anchor="nw", pady=20, padx=10) 721 | 722 | play = ct.CTkButton(self.title_frame, text="Play ", image=self.stop_img, font=("IBM Plex Sans", 30, "bold"), text_color="white", 723 | corner_radius=60, fg_color="#2d862d", hover_color="#2c7c2c", command=self.playPlaylist_song) 724 | play.pack(side=TOP, anchor="nw", padx=10, ipady=10, ipadx=10) 725 | 726 | if len(self.favourites) > 0: 727 | music_name = self.favourites[0].lower().replace(" ", "_") 728 | music_name = music_name.split(".") 729 | music_name[1] = ".png" 730 | music_name = str(music_name[0] + music_name[1]) 731 | title_image = ct.CTkImage(Image.open(os.path.join(image_path, f"{music_name}")), size=(250, 220)) 732 | title_song.configure(image=title_image) 733 | 734 | if len(self.favourites) == 0: 735 | title_song.configure(image=self.imgPlaylistFavourites) 736 | 737 | ######################################################### 738 | playlist_songs_frame = ct.CTkFrame(self.favourites_playlist_full, fg_color="transparent") 739 | 740 | for i in self.favourites: 741 | list_fav_song_frame = ct.CTkFrame(playlist_songs_frame, fg_color="#444") 742 | photo_name = self.favourites[0].lower().replace(" ", "_") 743 | photo_name = photo_name.split(".") 744 | photo_name[1] = ".png" 745 | photo_name = str(photo_name[0]) 746 | photo = ct.CTkImage(Image.open(os.path.join(image_path, f"{music_name}")), size=(40, 40)) 747 | 748 | songs_favourite = ct.CTkButton(list_fav_song_frame, text=i.split(".")[0], fg_color="transparent", hover_color="#444", font=("Poppins", 22, "bold"), 749 | image=photo, compound=LEFT, text_color="white") 750 | songs_favourite.pack(side=LEFT, fill=X, padx=10) 751 | 752 | singer_name = ct.CTkLabel(list_fav_song_frame, text=self.get_music_info(f"songs\\{i}")["artist"], font=("Poppins", 20, "bold")) # type: ignore 753 | singer_name.pack(side=RIGHT, padx=20) 754 | 755 | list_fav_song_frame.pack(side=TOP, fill=X, expand=False, ipady=10, padx=10, pady=10, ipadx=10) 756 | playlist_songs_frame.pack(side=BOTTOM, fill=X, expand=True, pady=10, padx=5) 757 | ######################################################### 758 | 759 | self.favourites_playlist_full.pack(side=TOP, fill=BOTH, expand=True, padx=10, pady=10) 760 | 761 | def update_songs_(self): 762 | global playlist_songs_frame 763 | i = len(self.favourites) 764 | if i == 0: 765 | playlist_songs_frame.destroy() 766 | else: 767 | playlist_songs_frame.destroy() 768 | playlist_songs_frame = ct.CTkFrame(self.favourites_playlist_full, fg_color="transparent") 769 | for i in self.favourites: 770 | list_fav_song_frame = ct.CTkFrame(playlist_songs_frame, fg_color="#444") 771 | photo_name = i.lower().replace(" ", "_") 772 | photo_name = photo_name.split(".") 773 | photo_name[1] = ".png" 774 | photo_name = str(photo_name[0]) 775 | photo = ct.CTkImage(Image.open(os.path.join(image_path, f"{photo_name}.png")), size=(40, 40)) 776 | songs_favourite = ct.CTkButton(list_fav_song_frame, text=i.split(".")[0], fg_color="transparent", hover_color="#444", font=("Poppins", 22, "bold"), 777 | image=photo, compound=LEFT, text_color="white") 778 | songs_favourite.pack(side=LEFT, fill=X, padx=10) 779 | 780 | singer_name = ct.CTkLabel(list_fav_song_frame, text=self.get_music_info(f"songs\\{i}")["artist"], font=("Poppins", 20, "bold")) # type: ignore 781 | singer_name.pack(side=RIGHT, padx=20) 782 | 783 | list_fav_song_frame.pack(side=TOP, fill=X, expand=False, ipady=10, padx=10, pady=10, ipadx=10) 784 | playlist_songs_frame.pack(side=BOTTOM, fill=X, expand=True, pady=10, padx=5) 785 | 786 | def updateFavouritePlaylistImage(self): 787 | global music_icon, image_path, title_song 788 | image_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "songs_images") 789 | if len(self.favourites) > 0: 790 | music_name = self.favourites[0].lower().replace(" ", "_") 791 | music_name = music_name.split(".") 792 | music_name[1] = ".png" 793 | music_name = str(music_name[0] + music_name[1]) 794 | music_icon = ct.CTkImage(Image.open(os.path.join(image_path, f"{music_name}")), size=(220, 220)) 795 | title_song.configure(image=music_icon) 796 | 797 | if len(self.favourites) == 0: 798 | title_song.configure(image=self.imgPlaylistFavourites) 799 | 800 | self.root.after(1000, self.updateFavouritePlaylistImage) 801 | 802 | def play_previous_song(self): 803 | try: 804 | self.play_music(self.previous_song[len(self.previous_song)-2]) 805 | except Exception as e: 806 | print(e) 807 | 808 | def loop_song(self): 809 | self.loop = True 810 | if self.music_playing: 811 | current_position = pygame.mixer.music.get_pos() / 1000 812 | # print(current_position) 813 | 814 | def add_favourite(self): 815 | if self.music_playing: 816 | if self.music_playing not in self.favourites: 817 | self.favourite.configure(image=self.favourite_img2) 818 | self.favourite.configure(command=self.remove_favourite) 819 | self.favourites.append(self.music_playing) 820 | self.update_songs_() 821 | else: 822 | pass 823 | 824 | def remove_favourite(self): 825 | if self.music_playing: 826 | try: 827 | self.favourite.configure(image=self.favourite_img) 828 | self.favourite.configure(command=self.add_favourite) 829 | self.favourites.remove(self.music_playing) 830 | self.updateFavouritePlaylistImage() 831 | self.update_songs_() 832 | except Exception as e: 833 | print(e) 834 | 835 | def spacebar_event(self, event): 836 | if self.music_playing: 837 | self.stop_music() 838 | self.root.bind("", self.spacebar_event_2) 839 | 840 | def spacebar_event_2(self, event): 841 | self.resume_music() 842 | self.root.bind("", self.spacebar_event) 843 | 844 | def slide_song(self): 845 | # if self.music_playing: 846 | # music_file = f"songs\\{self.music_playing}" 847 | # pygame.mixer.music.load(music_file) 848 | # music_length = pygame.mixer.Sound(music_file).get_length() 849 | # scale_at = int(self.slider.get()) / 100 * music_length 850 | # pygame.mixer.music.play(start=int(scale_at)) 851 | pass 852 | 853 | def get_music_info(self, music_name): 854 | artist = get_artist(music_name) 855 | # album = get_album(song) 856 | 857 | return { 858 | "artist" : artist, 859 | # "album" : album 860 | } 861 | 862 | def add_Music(self, music_name, music_image_name, tab="home"): 863 | self.all_songs.append(music_name) 864 | global song_image_path, song_img 865 | song_image_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "songs_images") 866 | song_img = ct.CTkImage(Image.open(os.path.join(song_image_path, music_image_name)), size=(280, 230)) 867 | 868 | if tab not in self.frames: 869 | self.frames[tab] = ct.CTkFrame(self.home_frame, fg_color=self.color_home_frame) 870 | 871 | song_button = ct.CTkButton(self.frames[tab], text=music_name, fg_color=self.color_home_frame, bg_color="transparent", corner_radius=10, 872 | image=song_img, command=lambda: self.play_music(f"{music_name}.mp3"), compound=TOP, font=("IBM Plex Sans", 20)) 873 | song_button.pack(side=LEFT, ipady=10, ipadx=0) 874 | self.frames[tab].pack(side=TOP, fill=X, pady=2) 875 | 876 | def add_audiobooks(self, audiobook_name, audiobook_image_name, tab="audiobooks"): 877 | global audiobooks_image_path, audiobook_img 878 | audiobooks_image_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "audiobooks\\audiobooksImage") 879 | audiobook_img = ct.CTkImage(Image.open(os.path.join(audiobooks_image_path, audiobook_image_name)), size=(190, 250)) 880 | 881 | if tab not in self.frames2: 882 | self.frames2[tab] = ct.CTkFrame(self.audio_frame, fg_color="transparent") 883 | 884 | audiobook_button = ct.CTkButton(self.frames2[tab], text="", fg_color="transparent", bg_color="transparent", hover_color="gray30", image=audiobook_img, command=lambda: self.play_audiobooks(audiobook_name)) 885 | audiobook_button.pack(side=LEFT, ipady=10, ipadx=8, padx=10) 886 | self.frames2[tab].pack(side=TOP, fill=X, pady=10, padx=30) 887 | 888 | def play_audiobooks(self, audiobook_name): 889 | self.favourite.pack_forget() 890 | author = {"Atomic Habits" : "James Clear", 891 | "Digital Minimalism" : "Cal Newport", 892 | "Rework" : "Jason Fried", 893 | "HyperFocus" : "Chris Bailey", 894 | "The Richest Man in Babylon" : "George Clason", 895 | "Essentialism" : "Greg Mekeown"} 896 | 897 | pygame.mixer.music.load(f"audiobooks\\{audiobook_name}.mp3") 898 | pygame.mixer.music.play() 899 | self.pause.configure(state="normal", image=self.pause_img) 900 | self.audiobooks_data = MP3(f"audiobooks\\{audiobook_name}.mp3") 901 | self.audiobooks_length = int(self.audiobooks_data.info.length) 902 | self.music_duration_label.configure(text=time.strftime('%M:%S', time.gmtime(self.audiobooks_length))) 903 | self.scale_update2() 904 | self.insertSongImage2(audiobook_name) 905 | 906 | author_name = author[audiobook_name] 907 | 908 | if len(author_name) > 16: 909 | self.play_control_frame.pack_configure(padx=20) 910 | if len(author_name) < 16: 911 | self.play_control_frame.pack_configure(padx=140) 912 | 913 | self.singer_name.configure(text=f"{author[audiobook_name]}") 914 | 915 | def play_music(self, music_name): 916 | self.favourite.pack(side=RIGHT, padx=80) 917 | if self.music_playing != music_name: 918 | pygame.mixer.music.load(f"songs\\{music_name}") 919 | pygame.mixer.music.play() 920 | self.pause.configure(state="normal", image=self.pause_img) 921 | self.music_data = MP3(f"songs\\{music_name}") 922 | self.music_length = int(self.music_data.info.length) 923 | self.music_duration_label.configure(text=time.strftime('%M:%S', time.gmtime(self.music_length))) 924 | self.scale_update() 925 | self.insertSongImage(music_name) 926 | self.configure_music(music_name) 927 | self.previous_song.append(music_name) 928 | artist_name = self.get_music_info(f"songs\\{music_name}")["artist"] 929 | self.singer_name.configure(text=artist_name) 930 | if len(artist_name) > 16: # type: ignore 931 | self.play_control_frame.pack_configure(padx=20) 932 | if len(artist_name) < 16: # type: ignore 933 | self.play_control_frame.pack_configure(padx=140) 934 | 935 | self.music_playing = music_name 936 | 937 | def configure_music(self, music_name): 938 | if music_name in self.favourites: 939 | self.favourite.configure(image=self.favourite_img2, command=self.remove_favourite) 940 | else: 941 | self.favourite.configure(image=self.favourite_img, command=self.add_favourite) 942 | 943 | def insertSongImage(self, image): 944 | music_name = image.lower().replace(" ", "_") 945 | music_name = music_name.split(".") 946 | music_name[1] = ".png" 947 | music_name = str(music_name[0] + music_name[1]) 948 | self.image = ct.CTkImage(Image.open(os.path.join(song_image_path, f"{music_name}")), size= (45, 45)) 949 | self.image_song_label.configure(image=self.image) 950 | 951 | def insertSongImage2(self, image): 952 | audiobook_name = image.lower() 953 | audiobook_name = audiobook_name.replace(" ", "_") 954 | audiobook_name = f"{audiobook_name}.png" 955 | self.image = ct.CTkImage(Image.open(os.path.join(audiobooks_image_path, f"{audiobook_name}")), size= (45, 45)) 956 | self.image_song_label.configure(image=self.image) 957 | 958 | def scale_update(self): 959 | try: 960 | self.root.after_cancel(self.updater2) 961 | self.updater2 = None 962 | except: 963 | pass 964 | self.slider.configure(to=self.music_data.info.length) 965 | current_position = pygame.mixer.music.get_pos() 966 | self.position = int(current_position / 1000) 967 | self.slider.set(int(current_position / 1000)) 968 | self.time_elapsed_label.configure(text=time.strftime('%M:%S', time.gmtime(self.slider.get()))) 969 | self.updater = self.root.after(1000, self.scale_update) 970 | 971 | def scale_update2(self): 972 | try: 973 | self.root.after_cancel(self.updater) 974 | self.updater = None 975 | except: 976 | pass 977 | self.slider.configure(to=self.audiobooks_data.info.length) 978 | current_position = pygame.mixer.music.get_pos() 979 | self.position = int(current_position / 1000) 980 | self.slider.set(int(current_position / 1000)) 981 | self.time_elapsed_label.configure(text=time.strftime('%M:%S', time.gmtime(self.slider.get()))) 982 | self.updater2 = self.root.after(1000, self.scale_update2) 983 | 984 | def stop_music(self): 985 | if pygame.mixer.music.get_busy(): 986 | pygame.mixer.music.pause() 987 | self.pause.configure(image=self.stop_img, command=self.resume_music) 988 | else: 989 | pass 990 | 991 | def resume_music(self): 992 | pygame.mixer.music.unpause() 993 | self.pause.configure(image=self.pause_img, command=self.stop_music) 994 | 995 | def select_frame_name(self, name): 996 | self.search.configure(fg_color="#444" if name == "search" else "transparent") 997 | self.home.configure(fg_color="#444" if name == "home" else "transparent") 998 | self.artists.configure(fg_color="#444" if name == "artists" else "transparent") 999 | self.trending.configure(fg_color="#444" if name == "trending" else "transparent") 1000 | self.audiobooks.configure(fg_color="#444" if name == "audiobooks" else "transparent") 1001 | self.settings.configure(fg_color="#444" if name == "settings" else "transparent") 1002 | self.favourites_btn.configure(fg_color="#444" if name == "favourites" else "transparent") 1003 | 1004 | if name == "search": 1005 | self.search_frame.pack(fill=BOTH, expand=True) 1006 | else: 1007 | self.search_frame.pack_forget() 1008 | if name == "home": 1009 | self.home_frame.pack(fill=BOTH, expand=True) 1010 | else: 1011 | self.home_frame.pack_forget() 1012 | if name == "artists": 1013 | self.discover_frame.pack(fill=BOTH, expand=True) 1014 | else: 1015 | self.discover_frame.pack_forget() 1016 | if name == "trending": 1017 | self.popular_frame.pack(fill=BOTH, expand=True) 1018 | else: 1019 | self.popular_frame.pack_forget() 1020 | if name == "audiobooks": 1021 | self.audiobooks_frame.pack(fill=BOTH, expand=True) 1022 | else: 1023 | self.audiobooks_frame.pack_forget() 1024 | if name == "favourites": 1025 | self.favourites_frame.pack(fill=BOTH, expand=True) 1026 | else: 1027 | self.favourites_frame.pack_forget() 1028 | if name == "settings": 1029 | self.settings_frame.pack(fill=BOTH, expand=True) 1030 | else: 1031 | self.settings_frame.pack_forget() 1032 | 1033 | def add_music(app): 1034 | # Music code here 1035 | app.add_Music(music_name="Let Me Down Slowly", music_image_name="let_me_down_slowly.png", tab="home1") 1036 | app.add_Music(music_name="Raghupathi Raghava Rajaram", music_image_name="raghupathi_raghava_rajaram.png", tab="home1") 1037 | app.add_Music(music_name="Ram Aayenge", music_image_name="ram_aayenge.png", tab="home1") 1038 | app.add_Music(music_name="Tu Jo Mila", music_image_name="tu_jo_mila.png", tab="home1") 1039 | 1040 | app.add_Music(music_name="Faded", music_image_name="faded.png", tab="home2") 1041 | app.add_Music(music_name="See you Again", music_image_name="see_you_again.png", tab="home2") 1042 | app.add_Music(music_name="Hymn For The Weekend", music_image_name="hymn_for_the_weekend.png", tab="home2") 1043 | app.add_Music(music_name="Into Your Arms", music_image_name="into_your_arms.png", tab="home2") 1044 | 1045 | app.add_Music(music_name="Infinity", music_image_name="infinity.png", tab="home3") 1046 | app.add_Music(music_name="Can We Kiss Forever", music_image_name="can_we_kiss_forever.png", tab="home3") 1047 | app.add_Music(music_name="Arcade", music_image_name="arcade.png", tab="home3") 1048 | app.add_Music(music_name="Safari", music_image_name="safari.png", tab="home3") 1049 | 1050 | app.add_Music(music_name="Fearless", music_image_name="fearless.png", tab="home4") 1051 | app.add_Music(music_name="Tum Hi Ho", music_image_name="tum_hi_ho.png", tab="home4") 1052 | app.add_Music(music_name="Khairiyat", music_image_name="Khairiyat.png", tab="home4") 1053 | app.add_Music(music_name="Baaton Ko Teri", music_image_name="baaton_ko_teri.png", tab="home4") 1054 | 1055 | app.add_Music(music_name="Khamoshiyan", music_image_name="khamoshiyan.png", tab="home5") 1056 | app.add_Music(music_name="Tere Sang Yaara", music_image_name="tere_sang_yaara.png", tab="home5") 1057 | app.add_Music(music_name="Chhod Diya", music_image_name="chhod_diya.png", tab="home5") 1058 | app.add_Music(music_name="Phir Mohabbat", music_image_name="phir_mohabbat.png", tab="home5") 1059 | 1060 | # AudioBooks code here 1061 | app.add_audiobooks(audiobook_name="Atomic Habits", audiobook_image_name="atomic_habits.png", tab="audiobooks1") 1062 | app.add_audiobooks(audiobook_name="Digital Minimalism", audiobook_image_name="digital_minimalism.png", tab="audiobooks1") 1063 | app.add_audiobooks(audiobook_name="Rework", audiobook_image_name="rework.png", tab="audiobooks1") 1064 | app.add_audiobooks(audiobook_name="HyperFocus", audiobook_image_name="hyperfocus.png", tab="audiobooks1") 1065 | app.add_audiobooks(audiobook_name="The Richest Man in Babylon", audiobook_image_name="the_richest_man_in_babylon.png", tab="audiobooks1") 1066 | app.add_audiobooks(audiobook_name="Essentialism", audiobook_image_name="essentialism.png", tab="audiobooks2") 1067 | 1068 | if __name__ == "__main__": 1069 | pygame.mixer.init() 1070 | 1071 | root = ct.CTk() 1072 | 1073 | if os.path.exists("data.txt"): 1074 | if os.path.exists("imagename.txt"): 1075 | app = Spotify(root) 1076 | add_music(app) 1077 | else: 1078 | IntroPage(root) 1079 | else: 1080 | IntroPage(root) 1081 | 1082 | cProfile.run("root.mainloop()", sort="time") 1083 | -------------------------------------------------------------------------------- /audiobooks/Atomic Habits.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/audiobooks/Atomic Habits.mp3 -------------------------------------------------------------------------------- /audiobooks/Digital Minimalism.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/audiobooks/Digital Minimalism.mp3 -------------------------------------------------------------------------------- /audiobooks/Essentialism.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/audiobooks/Essentialism.mp3 -------------------------------------------------------------------------------- /audiobooks/Hyperfocus.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/audiobooks/Hyperfocus.mp3 -------------------------------------------------------------------------------- /audiobooks/Rework.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/audiobooks/Rework.mp3 -------------------------------------------------------------------------------- /audiobooks/The Richest Man In Babylon.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/audiobooks/The Richest Man In Babylon.mp3 -------------------------------------------------------------------------------- /audiobooks/audiobooksImage/atomic_habits.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/audiobooks/audiobooksImage/atomic_habits.png -------------------------------------------------------------------------------- /audiobooks/audiobooksImage/digital_minimalism.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/audiobooks/audiobooksImage/digital_minimalism.png -------------------------------------------------------------------------------- /audiobooks/audiobooksImage/essentialism.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/audiobooks/audiobooksImage/essentialism.png -------------------------------------------------------------------------------- /audiobooks/audiobooksImage/hyperfocus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/audiobooks/audiobooksImage/hyperfocus.png -------------------------------------------------------------------------------- /audiobooks/audiobooksImage/rework.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/audiobooks/audiobooksImage/rework.png -------------------------------------------------------------------------------- /audiobooks/audiobooksImage/the_richest_man_in_babylon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/audiobooks/audiobooksImage/the_richest_man_in_babylon.png -------------------------------------------------------------------------------- /avator/avator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/avator/avator.png -------------------------------------------------------------------------------- /avator/avator1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/avator/avator1.png -------------------------------------------------------------------------------- /avator/avator10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/avator/avator10.png -------------------------------------------------------------------------------- /avator/avator11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/avator/avator11.png -------------------------------------------------------------------------------- /avator/avator12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/avator/avator12.png -------------------------------------------------------------------------------- /avator/avator13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/avator/avator13.png -------------------------------------------------------------------------------- /avator/avator14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/avator/avator14.png -------------------------------------------------------------------------------- /avator/avator15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/avator/avator15.png -------------------------------------------------------------------------------- /avator/avator16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/avator/avator16.png -------------------------------------------------------------------------------- /avator/avator17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/avator/avator17.png -------------------------------------------------------------------------------- /avator/avator2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/avator/avator2.png -------------------------------------------------------------------------------- /avator/avator3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/avator/avator3.png -------------------------------------------------------------------------------- /avator/avator4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/avator/avator4.png -------------------------------------------------------------------------------- /avator/avator5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/avator/avator5.png -------------------------------------------------------------------------------- /avator/avator6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/avator/avator6.png -------------------------------------------------------------------------------- /avator/avator7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/avator/avator7.png -------------------------------------------------------------------------------- /avator/avator8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/avator/avator8.png -------------------------------------------------------------------------------- /avator/avator9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/avator/avator9.png -------------------------------------------------------------------------------- /avator/left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/avator/left.png -------------------------------------------------------------------------------- /avator/right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/avator/right.png -------------------------------------------------------------------------------- /extract_info/extract_album.py: -------------------------------------------------------------------------------- 1 | import eyed3, re 2 | 3 | def get_album(file_path): 4 | try: 5 | audio_file = eyed3.load(file_path) 6 | 7 | if audio_file.tag.album: 8 | filtered_text = re.sub(r'\[[^\]]*\]', '', audio_file.tag.album) 9 | return filtered_text 10 | else: 11 | return None 12 | except Exception as e: 13 | return f"Error : {e}" -------------------------------------------------------------------------------- /extract_info/extract_artist.py: -------------------------------------------------------------------------------- 1 | import eyed3 2 | 3 | def get_artist(file_path): 4 | try: 5 | audio_file = eyed3.load(file_path) 6 | 7 | if audio_file.tag.artist: 8 | return audio_file.tag.artist 9 | else: 10 | return None 11 | except Exception as e: 12 | return f"Error : {e}" -------------------------------------------------------------------------------- /images/avator2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/avator2.png -------------------------------------------------------------------------------- /images/bookopen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/bookopen.png -------------------------------------------------------------------------------- /images/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/close.png -------------------------------------------------------------------------------- /images/delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/delete.png -------------------------------------------------------------------------------- /images/delete2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/delete2.png -------------------------------------------------------------------------------- /images/edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/edit.png -------------------------------------------------------------------------------- /images/edit2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/edit2.png -------------------------------------------------------------------------------- /images/eyes_closed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/eyes_closed.png -------------------------------------------------------------------------------- /images/eyes_open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/eyes_open.png -------------------------------------------------------------------------------- /images/gradient.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/gradient.png -------------------------------------------------------------------------------- /images/headphones.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/headphones.png -------------------------------------------------------------------------------- /images/heart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/heart.png -------------------------------------------------------------------------------- /images/heart1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/heart1.png -------------------------------------------------------------------------------- /images/heart2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/heart2.png -------------------------------------------------------------------------------- /images/heart3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/heart3.png -------------------------------------------------------------------------------- /images/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/home.png -------------------------------------------------------------------------------- /images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/icon.png -------------------------------------------------------------------------------- /images/lock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/lock.png -------------------------------------------------------------------------------- /images/loop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/loop.png -------------------------------------------------------------------------------- /images/mail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/mail.png -------------------------------------------------------------------------------- /images/man.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/man.png -------------------------------------------------------------------------------- /images/max.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/max.png -------------------------------------------------------------------------------- /images/min.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/min.png -------------------------------------------------------------------------------- /images/minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/minus.png -------------------------------------------------------------------------------- /images/myHeart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/myHeart.png -------------------------------------------------------------------------------- /images/myHeart2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/myHeart2.png -------------------------------------------------------------------------------- /images/myHeart3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/myHeart3.png -------------------------------------------------------------------------------- /images/pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/pause.png -------------------------------------------------------------------------------- /images/play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/play.png -------------------------------------------------------------------------------- /images/playlist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/playlist.png -------------------------------------------------------------------------------- /images/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/plus.png -------------------------------------------------------------------------------- /images/repeat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/repeat.png -------------------------------------------------------------------------------- /images/rise.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/rise.png -------------------------------------------------------------------------------- /images/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/search.png -------------------------------------------------------------------------------- /images/search2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/search2.png -------------------------------------------------------------------------------- /images/settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/settings.png -------------------------------------------------------------------------------- /images/shuffle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/shuffle.png -------------------------------------------------------------------------------- /images/shuffle1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/shuffle1.png -------------------------------------------------------------------------------- /images/skip-back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/skip-back.png -------------------------------------------------------------------------------- /images/skip-forward.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/skip-forward.png -------------------------------------------------------------------------------- /images/song.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/song.png -------------------------------------------------------------------------------- /images/spotify.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/spotify.ico -------------------------------------------------------------------------------- /images/spotify.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/spotify.png -------------------------------------------------------------------------------- /images/spotify2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/spotify2.png -------------------------------------------------------------------------------- /images/spotify_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/spotify_bg.png -------------------------------------------------------------------------------- /images/star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/star.png -------------------------------------------------------------------------------- /images/x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/images/x.png -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | eyed3 2 | mutagen 3 | pygame 4 | tkinter 5 | customtkinter 6 | PIL 7 | -------------------------------------------------------------------------------- /singersImage/alan_walker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/singersImage/alan_walker.png -------------------------------------------------------------------------------- /singersImage/alec_benjamin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/singersImage/alec_benjamin.png -------------------------------------------------------------------------------- /singersImage/alisha_chinai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/singersImage/alisha_chinai.png -------------------------------------------------------------------------------- /singersImage/arijit_singh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/singersImage/arijit_singh.png -------------------------------------------------------------------------------- /singersImage/atif_aslam.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/singersImage/atif_aslam.png -------------------------------------------------------------------------------- /singersImage/duncan_laurence.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/singersImage/duncan_laurence.png -------------------------------------------------------------------------------- /singersImage/g_gayathri_devi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/singersImage/g_gayathri_devi.png -------------------------------------------------------------------------------- /singersImage/kina.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/singersImage/kina.png -------------------------------------------------------------------------------- /singersImage/kk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/singersImage/kk.png -------------------------------------------------------------------------------- /singersImage/pamphara_thakur.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/singersImage/pamphara_thakur.png -------------------------------------------------------------------------------- /singersImage/sachet_tandon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/singersImage/sachet_tandon.png -------------------------------------------------------------------------------- /singersImage/sarena.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/singersImage/sarena.png -------------------------------------------------------------------------------- /singersImage/swati_mishra.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/singersImage/swati_mishra.png -------------------------------------------------------------------------------- /singersImage/uma_mohan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/singersImage/uma_mohan.png -------------------------------------------------------------------------------- /songs/Baaton Ko Teri.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs/Baaton Ko Teri.mp3 -------------------------------------------------------------------------------- /songs/Can We Kiss Forever.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs/Can We Kiss Forever.mp3 -------------------------------------------------------------------------------- /songs/Chhod Diya.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs/Chhod Diya.mp3 -------------------------------------------------------------------------------- /songs/Faded.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs/Faded.mp3 -------------------------------------------------------------------------------- /songs/Fearless.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs/Fearless.mp3 -------------------------------------------------------------------------------- /songs/Hymn For The Weekend.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs/Hymn For The Weekend.mp3 -------------------------------------------------------------------------------- /songs/Infinity.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs/Infinity.mp3 -------------------------------------------------------------------------------- /songs/Into Your Arms.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs/Into Your Arms.mp3 -------------------------------------------------------------------------------- /songs/Khairiyat.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs/Khairiyat.mp3 -------------------------------------------------------------------------------- /songs/Khamoshiyan.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs/Khamoshiyan.mp3 -------------------------------------------------------------------------------- /songs/Let Me Down Slowly.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs/Let Me Down Slowly.mp3 -------------------------------------------------------------------------------- /songs/Phir Mohabbat.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs/Phir Mohabbat.mp3 -------------------------------------------------------------------------------- /songs/Raghupathi Raghava Rajaram.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs/Raghupathi Raghava Rajaram.mp3 -------------------------------------------------------------------------------- /songs/Ram Aayenge.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs/Ram Aayenge.mp3 -------------------------------------------------------------------------------- /songs/Safari.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs/Safari.mp3 -------------------------------------------------------------------------------- /songs/See You Again.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs/See You Again.mp3 -------------------------------------------------------------------------------- /songs/Tere Sang Yaara.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs/Tere Sang Yaara.mp3 -------------------------------------------------------------------------------- /songs/Tu Jo Mila.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs/Tu Jo Mila.mp3 -------------------------------------------------------------------------------- /songs/Tum Hi Ho.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs/Tum Hi Ho.mp3 -------------------------------------------------------------------------------- /songs_images/arcade.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs_images/arcade.png -------------------------------------------------------------------------------- /songs_images/baaton_ko_teri.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs_images/baaton_ko_teri.png -------------------------------------------------------------------------------- /songs_images/can_we_kiss_forever.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs_images/can_we_kiss_forever.png -------------------------------------------------------------------------------- /songs_images/chhod_diya.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs_images/chhod_diya.png -------------------------------------------------------------------------------- /songs_images/chura_ke_dil_mera.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs_images/chura_ke_dil_mera.png -------------------------------------------------------------------------------- /songs_images/chura_liya_hai_tumne_jo_dil_ko.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs_images/chura_liya_hai_tumne_jo_dil_ko.png -------------------------------------------------------------------------------- /songs_images/dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs_images/dark.png -------------------------------------------------------------------------------- /songs_images/dil_meri_na_sune.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs_images/dil_meri_na_sune.png -------------------------------------------------------------------------------- /songs_images/faded.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs_images/faded.png -------------------------------------------------------------------------------- /songs_images/fearless.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs_images/fearless.png -------------------------------------------------------------------------------- /songs_images/hamari_adhuri_kahani.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs_images/hamari_adhuri_kahani.jpg -------------------------------------------------------------------------------- /songs_images/hamari_adhuri_kahani.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs_images/hamari_adhuri_kahani.png -------------------------------------------------------------------------------- /songs_images/hymn_for_the_weekend.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs_images/hymn_for_the_weekend.png -------------------------------------------------------------------------------- /songs_images/infinity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs_images/infinity.png -------------------------------------------------------------------------------- /songs_images/into_your_arms.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs_images/into_your_arms.png -------------------------------------------------------------------------------- /songs_images/khairiyat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs_images/khairiyat.png -------------------------------------------------------------------------------- /songs_images/khamoshiyan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs_images/khamoshiyan.png -------------------------------------------------------------------------------- /songs_images/let_me_down_slowly.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs_images/let_me_down_slowly.png -------------------------------------------------------------------------------- /songs_images/phir_mohabbat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs_images/phir_mohabbat.png -------------------------------------------------------------------------------- /songs_images/raghupathi_raghava_rajaram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs_images/raghupathi_raghava_rajaram.png -------------------------------------------------------------------------------- /songs_images/ram_aayenge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs_images/ram_aayenge.png -------------------------------------------------------------------------------- /songs_images/safari.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs_images/safari.png -------------------------------------------------------------------------------- /songs_images/see_you_again.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs_images/see_you_again.png -------------------------------------------------------------------------------- /songs_images/shiv_tandav_stotram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs_images/shiv_tandav_stotram.png -------------------------------------------------------------------------------- /songs_images/shree_hari_stotram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs_images/shree_hari_stotram.png -------------------------------------------------------------------------------- /songs_images/survey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs_images/survey.png -------------------------------------------------------------------------------- /songs_images/tera_hone_laga_hoon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs_images/tera_hone_laga_hoon.png -------------------------------------------------------------------------------- /songs_images/tere_sang_yaara.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs_images/tere_sang_yaara.png -------------------------------------------------------------------------------- /songs_images/theme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs_images/theme.png -------------------------------------------------------------------------------- /songs_images/tu_jo_mila.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs_images/tu_jo_mila.png -------------------------------------------------------------------------------- /songs_images/tum_hi_ho.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SarthakTools/Spotify/a8f9a1be27084b63506ccbc50a0cede052ec4824/songs_images/tum_hi_ho.png --------------------------------------------------------------------------------