-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcola_reproduccion.py
148 lines (130 loc) · 5.89 KB
/
cola_reproduccion.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
from cancion import Cancion
from tinytag import TinyTagException
from pila import Pila
from lista_enlazada import ListaEnlazada
EXTENSIONES_ACEPTADAS = ("wav", "mp3", "flac", "ogg", "wma")
class ColaDeReproduccion:
"""Clase que representa la cola de reproduccion del reproductor. Permite agregar y remover
canciones, ademas de poder hacer y deshacer estas acciones. Las canciones se guardan en la
cola como objetos de clase Cancion."""
AGREGADA = 1
REMOVIDA = 0
def __init__(self, lista_canciones=[]):
""" Recibe una lista de objetos de clase Cancion con las canciones que se quieren
reproducir."""
lista = ListaEnlazada()
for cancion in lista_canciones:
lista.insert(cancion)
self.lista_canciones = lista
self.acciones_tomadas = Pila()
self.acciones_deshechas = Pila()
self.actual = 0
def cancion_actual(self):
""" Devuelve un objeto de clase Cancion que corresponde a la cancion actual, o None si no
hay canciones cargadas en la cola."""
if self.lista_canciones.esta_vacia():
return None
try:
cancion = self.lista_canciones.get_elemento(self.actual)
except IndexError:
return
return cancion
def cancion_siguiente(self):
""" Devuelve un objeto de clase Cancion que corresponde a la cancion siguiente en la cola,
o None si no hay mas canciones."""
if len(self.lista_canciones) < 1:
return None
try:
cancion = self.lista_canciones.get_elemento(self.actual + 1)
self.actual += 1
except IndexError:
return
return cancion
def cancion_anterior(self):
""" Devuelve un objeto de clase Cancion que corresponde a la cancion anterior en la cola,
o None si no hay canciones en la misma o la actual es la primera de la cola."""
if len(self.lista_canciones) < 1:
return None
try:
cancion = self.lista_canciones.get_elemento(self.actual - 1)
self.actual -= 1
except IndexError: #No hay cancion anterior
return
return cancion
def agregar_cancion(self, ruta_cancion):
""" Agrega una Cancion a la cola a partir de su ruta. Devuelve True si se agrego
correctamente, False en caso contrario. Esta accion puede deshacerse y rehacerse."""
try:
self.agregar_cancion_sin_guardar(ruta_cancion)
self.guardar_accion(ruta_cancion, self.AGREGADA)
return True
except (TinyTagException, LookupError, OSError):
return False
def remover_cancion(self, ruta_cancion):
""" Remueve una Cancion de la cola a partir de su ruta. Devuelve True si se removio
correctamente, False en caso contrario. Esta accion puede deshacerse y rehacerse."""
try:
resultado = self.remover_cancion_sin_guardar(ruta_cancion)
self.guardar_accion(ruta_cancion, self.REMOVIDA)
return resultado
except (TinyTagException, LookupError, OSError):
return False
def deshacer_modificacion(self):
""" Deshace la ultima accion realizada. Devuelve True si pudo deshacerse, False en caso
contrario."""
try:
ruta_ultima_cancion, ultima_accion = self.acciones_tomadas.desapilar()
if ultima_accion == self.AGREGADA:
self.remover_cancion_sin_guardar(ruta_ultima_cancion)
self.acciones_deshechas.apilar((ruta_ultima_cancion, self.AGREGADA))
return True
self.agregar_cancion_sin_guardar(ruta_ultima_cancion)
self.acciones_deshechas.apilar((ruta_ultima_cancion, self.REMOVIDA))
return True
except (ValueError, IndexError):
return False
def rehacer_modificacion(self):
""" Rehace la ultima accion que se deshizo. Devuelve True si pudo rehacerse, False en caso
contrario."""
try:
ruta_ultima_cancion, ultima_accion = self.acciones_deshechas.desapilar()
if ultima_accion == self.AGREGADA:
self.agregar_cancion_sin_guardar(ruta_ultima_cancion)
self.acciones_tomadas.apilar((ruta_ultima_cancion, self.AGREGADA))
return True
self.remover_cancion_sin_guardar(ruta_ultima_cancion)
self.acciones_tomadas.apilar((ruta_ultima_cancion, self.REMOVIDA))
return True
except (ValueError, IndexError):
return False
def obtener_n_siguientes(self, n_canciones):
""" Devuelve una lista con las siguientes n canciones. Si en la cola de reproduccion
quedan menos canciones que las pedidas, la lista contendra menos elementos que los
pedidos."""
if self.lista_canciones.esta_vacia():
return None
lista = []
for i in range(n_canciones):
try:
lista.append(self.lista_canciones.get_elemento(self.actual + 1 + i))
except IndexError:
return lista
return lista
def __str__(self):
return str(self.lista_canciones)
def guardar_accion(self, ruta_cancion, accion):
"""Guarda la accion como una tupla (ruta_cancion, accion)."""
self.acciones_tomadas.apilar((ruta_cancion, accion))
def agregar_cancion_sin_guardar(self, ruta_cancion):
"""Agrega la cancion a la lista de reproduccion."""
cancion = Cancion(ruta_cancion)
self.lista_canciones.insert(cancion)
def remover_cancion_sin_guardar(self, ruta_cancion):
"""Remueve la cancion de la lista de reproduccion.
Devuelve True en caso que sea exitoso y False en caso contrario."""
cancion = Cancion(ruta_cancion)
posicion = self.lista_canciones.index(cancion)
if posicion:
self.lista_canciones.pop(posicion)
return True
return False