Adición de ficha por peli

This commit is contained in:
perro tuerto 2022-11-15 18:17:04 -08:00
parent 0d0c2e156b
commit 49903505c7
12 changed files with 411 additions and 54 deletions

View File

@ -87,12 +87,17 @@ class AdminMovie(admin.ModelAdmin):
try:
server = Mastodon(
<<<<<<< HEAD
<<<<<<< HEAD
access_token=settings.TOKEN_MASTODON,
api_base_url=settings.URL_MASTODON,
=======
access_token=settings.TOKEN_MASTODON, api_base_url=settings.URL_MASTODON
>>>>>>> a468c37 (Aplicación de 'black')
=======
access_token=settings.TOKEN_MASTODON,
api_base_url=settings.URL_MASTODON,
>>>>>>> 098cb26 (Adición de ficha por peli)
)
media = server.media_post(cartel.read(), media_type)
@ -105,14 +110,20 @@ class AdminMovie(admin.ModelAdmin):
url = f"https://api.telegram.org/bot{settings.TOKEN_TELEGRAM}/sendPhoto"
url_cartel = settings.URL_CDN.format(cartel)
<<<<<<< HEAD
<<<<<<< HEAD
=======
>>>>>>> 098cb26 (Adición de ficha por peli)
data = {
"chat_id": settings.CHAT_ID,
"photo": url_cartel,
"caption": message,
}
<<<<<<< HEAD
=======
data = {"chat_id": settings.CHAT_ID, "photo": url_cartel, "caption": message}
>>>>>>> a468c37 (Aplicación de 'black')
=======
>>>>>>> 098cb26 (Adición de ficha por peli)
result = httpx.post(url, data=data).json()
return

View File

@ -17,9 +17,7 @@ class LatestMoviesFeed(Feed):
return item.name
def item_description(self, item):
message = (
f"{item.name}, Dirigida por: {item.directors.all()[0]}, Año: {item.year}"
)
message = f"{item.name}, Dirigida por: {item.directors.all()[0]}, Año: {item.year}"
return message
def item_link(self, item):

View File

@ -66,10 +66,14 @@ class Migration(migrations.Migration):
),
),
<<<<<<< HEAD
<<<<<<< HEAD
=======
>>>>>>> 098cb26 (Adición de ficha por peli)
(
"name",
models.CharField(max_length=500, verbose_name="Nombre"),
),
<<<<<<< HEAD
(
"date_born",
models.DateField(
@ -83,6 +87,14 @@ class Migration(migrations.Migration):
models.DateField(
blank=True, null=True, verbose_name="Fecha de nacimiento"
>>>>>>> a468c37 (Aplicación de 'black')
=======
(
"date_born",
models.DateField(
blank=True,
null=True,
verbose_name="Fecha de nacimiento",
>>>>>>> 098cb26 (Adición de ficha por peli)
),
),
(
@ -91,6 +103,7 @@ class Migration(migrations.Migration):
),
(
"is_director",
<<<<<<< HEAD
<<<<<<< HEAD
models.BooleanField(
default=False, verbose_name="Es Director"
@ -98,6 +111,11 @@ class Migration(migrations.Migration):
=======
models.BooleanField(default=False, verbose_name="Es Director"),
>>>>>>> a468c37 (Aplicación de 'black')
=======
models.BooleanField(
default=False, verbose_name="Es Director"
),
>>>>>>> 098cb26 (Adición de ficha por peli)
),
(
"photo",
@ -137,13 +155,19 @@ class Migration(migrations.Migration):
),
),
<<<<<<< HEAD
<<<<<<< HEAD
=======
>>>>>>> 098cb26 (Adición de ficha por peli)
(
"name",
models.CharField(max_length=1000, verbose_name="Nombre"),
),
<<<<<<< HEAD
=======
("name", models.CharField(max_length=1000, verbose_name="Nombre")),
>>>>>>> a468c37 (Aplicación de 'black')
=======
>>>>>>> 098cb26 (Adición de ficha por peli)
(
"original_name",
models.CharField(
@ -164,6 +188,7 @@ class Migration(migrations.Migration):
),
(
"year",
<<<<<<< HEAD
<<<<<<< HEAD
models.PositiveSmallIntegerField(
default=1900, verbose_name="Año"
@ -171,6 +196,11 @@ class Migration(migrations.Migration):
=======
models.PositiveSmallIntegerField(default=1900, verbose_name="Año"),
>>>>>>> a468c37 (Aplicación de 'black')
=======
models.PositiveSmallIntegerField(
default=1900, verbose_name="Año"
),
>>>>>>> 098cb26 (Adición de ficha por peli)
),
(
"duration",
@ -189,6 +219,7 @@ class Migration(migrations.Migration):
),
(
"count",
<<<<<<< HEAD
<<<<<<< HEAD
models.PositiveIntegerField(
default=0, verbose_name="Descargas"
@ -196,6 +227,11 @@ class Migration(migrations.Migration):
=======
models.PositiveIntegerField(default=0, verbose_name="Descargas"),
>>>>>>> a468c37 (Aplicación de 'black')
=======
models.PositiveIntegerField(
default=0, verbose_name="Descargas"
),
>>>>>>> 098cb26 (Adición de ficha por peli)
),
(
"stars",

View File

@ -76,6 +76,7 @@ class Person(models.Model):
class MovieQuerySet(models.QuerySet):
<<<<<<< HEAD
<<<<<<< HEAD
def random_pick(self, random_max=6, min_items=20, **kwargs):
all = list(Movie.objects.filter(**kwargs).values())
@ -121,16 +122,24 @@ class MovieQuerySet(models.QuerySet):
return url + img.url
def random_pick(self, random_max=5, **kwargs):
=======
def random_pick(self, random_max=6, min_items=20, **kwargs):
>>>>>>> 098cb26 (Adición de ficha por peli)
all = list(Movie.objects.filter(**kwargs).values())
if len(all) > random_max:
return random.sample(all, random_max)
else:
all = self.fix_all_data(all)
if len(all) < min_items:
return None
elif len(all) < random_max:
return all
else:
return random.sample(all, random_max)
def top_pick(self, key, top_max=5):
def top_pick(self, key, top_max=6):
all = list(Movie.objects.order_by(f"-{key}").values())
all = self.fix_all_data(all)
return all[:top_max]
<<<<<<< HEAD
<<<<<<< HEAD
def top_random_pick(self, key, top_max = 5):
all = list(Movie.objects.order_by(f'-{key}').values())
@ -139,6 +148,11 @@ class MovieQuerySet(models.QuerySet):
def top_random_pick(self, key, top_max=5):
all = list(Movie.objects.order_by(f"-{key}").values())
>>>>>>> a468c37 (Aplicación de 'black')
=======
def top_random_pick(self, key, top_max=6):
all = list(Movie.objects.order_by(f"-{key}").values())
all = self.fix_all_data(all)
>>>>>>> 098cb26 (Adición de ficha por peli)
top = []
for movie in all:
if movie[key] == all[0][key]:
@ -243,17 +257,23 @@ class MovieQuerySet(models.QuerySet):
def home_pick(self):
genders = list(Gender.objects.values_list("id", flat=True))
sections = {
sections = self.home_sections()
for gender in genders:
key = Gender.objects.get(pk=gender).name
picked = self.random_pick(genders=gender)
if picked:
sections["genders"][key] = picked
return sections
def home_sections(self):
return {
"Novedades": self.top_pick("id"),
"Mejor valorados": self.top_random_pick("stars"),
"Más descargados": self.top_pick("count"),
"genders": {},
}
for gender in genders:
key = Gender.objects.get(pk=gender).name
sections["genders"][key] = self.random_pick(genders=gender)
return sections
<<<<<<< HEAD
def get_directors(self):
data = (
self.distinct()
@ -262,6 +282,39 @@ class MovieQuerySet(models.QuerySet):
)
return data
>>>>>>> fb23014 (Inicio de diseño)
=======
def fix_all_data(self, movies):
for movie in movies:
self.fix_data(movie)
return movies
def fix_data(self, movie):
movie["count_formatted"] = self.set_count(movie["count"])
movie["stars_icons"] = self.set_stars(movie["stars"])
movie["file_name"] = self.fix_path(movie["file_name"])
movie["cartel"] = self.fix_path(movie["cartel"])
def fix_path(self, el):
if settings.DEBUG:
return settings.URL_CDN.format(el)
else:
return settings.MEDIA_ROOT / el
def set_stars(self, num):
stars = "" * num
while len(stars) < 5:
stars += ""
return stars
def set_count(self, num):
return "{:,}".format(num)
def get_movie(self, id):
movie = Movie.objects.get(pk=id).__dict__
movie.pop("_state")
self.fix_data(movie)
return movie
>>>>>>> 098cb26 (Adición de ficha por peli)
def upload_cartel(instance, filename):
@ -292,6 +345,7 @@ class Movie(models.Model):
genders = models.ManyToManyField(
Gender, related_name="genders", verbose_name="Género", blank=True
)
<<<<<<< HEAD
<<<<<<< HEAD
cartel = models.ImageField(
"Cartel", upload_to=upload_cartel, null=True, blank=True
@ -299,6 +353,11 @@ class Movie(models.Model):
=======
cartel = models.ImageField("Cartel", upload_to=upload_cartel, null=True, blank=True)
>>>>>>> fb23014 (Inicio de diseño)
=======
cartel = models.ImageField(
"Cartel", upload_to=upload_cartel, null=True, blank=True
)
>>>>>>> 098cb26 (Adición de ficha por peli)
count = models.PositiveIntegerField("Descargas", default=0)
stars = models.PositiveSmallIntegerField("Estrellas", default=0)
published = models.BooleanField("¿Publicar?", default=True)

View File

@ -1,4 +1,7 @@
<<<<<<< HEAD
<<<<<<< HEAD
=======
>>>>>>> 098cb26 (Adición de ficha por peli)
/* BASE */
:root {
@ -11,6 +14,7 @@
}
#nav.is-fixed-top {
<<<<<<< HEAD
position: sticky;
top: -1px;
}
@ -326,3 +330,195 @@
top: -1px;
}
>>>>>>> fb23014 (Inicio de diseño)
=======
position: sticky;
top: -1px;
}
#menu.force-display {
display: flex !important;
}
/* Cada flecha en los títulos de secciones */
.arrows {
font-size: 1.5rem;
}
.arrows:before {
content: " ";
}
/* HOME */
/* Cada sección de pelis */
.hero-cartels {
margin-bottom: 0;
padding-bottom: 0;
}
.cartels {
clear: both;
width: calc(100% + 3rem);
margin-left: -1.5rem !important;
padding-left: 0;
display: grid;
align-items: center;
grid-template-columns: repeat(1, 1fr);
}
@media screen and (min-width: 300px) {
.cartels {
grid-template-columns: repeat(2, 1fr);
}
}
@media screen and (min-width: 450px) {
.cartels {
grid-template-columns: repeat(3, 1fr);
}
}
@media screen and (min-width: 600px) {
.cartels {
grid-template-columns: repeat(4, 1fr);
}
}
@media screen and (min-width: 750px) {
.cartels {
grid-template-columns: repeat(5, 1fr);
}
}
@media screen and (min-width: 900px) {
.cartels {
grid-template-columns: repeat(6, 1fr);
}
}
@media screen and (min-width: 1920px) {
.cartels {
width: auto;
margin: 0 !important;
grid-template-columns: repeat(6, 1fr);
}
}
/* Cada peli */
.cartel {
position: relative;
float: left;
min-width: 150px;
min-height: 225px;
max-width: 300px;
max-height: 450px;
}
.cartel img {
object-fit: cover;
}
.cartel .info-container {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
background-color: rgba(0,0,0,.5);
z-index: 102;
}
/* HOME / MOVIE */
/* Cada ficha de peli */
.movie-head {
padding: 2rem 2rem 0 2rem !important;
}
.movie-body {
padding: 2rem !important;
}
.movie-body video {
width: 100%;
height: auto;
}
.info {
position: fixed;
width: 90%;
height: 90vh;
background-color: var(--color-background);
z-index: 103;
}
.info .is-fullheight {
height: 100%;
min-height: 100%;
}
.stats span {
padding-right: 2rem;
}
.stars {
font-size: 1.5rem;
}
/* Despliegue de la ficha; Cfr:
* https://stackoverflow.com/questions/42177216/manipulate-css-class-without-javascript
* https://stackoverflow.com/questions/55858255/custom-checkbox-with-css-before-not-working-in-firefox-edge
*/
.toggle:checked ~ .info-container {
display: flex;
align-items: center;
justify-content: center;
}
.toggle {
position: absolute;
z-index: 100;
width: 100%;
height: 100%;
opacity: 0;
cursor: pointer;
}
.toggle + label {
visibility: visible;
content: "";
display: none;
color: white;
text-align: center;
font-size: 3rem;
background: var(--color-background);
cursor: pointer;
}
.toggle:checked {
display: block;
visibility: 0;
z-index: 104;
}
.toggle:checked ~ label {
z-index: 103;
display: flex;
align-items: center;
justify-content: center;
}
.toggle:checked,
.toggle:checked ~ label {
position: fixed;
top: calc(5vh + 1rem);
right: calc(5vw + 1rem);
width: 2rem;
height: 2rem;
}
>>>>>>> 098cb26 (Adición de ficha por peli)

View File

@ -1,4 +1,5 @@
<<<<<<< HEAD
<<<<<<< HEAD
document.addEventListener('DOMContentLoaded', () => {
modMenu();
});
@ -15,23 +16,37 @@ function modMenu() {
const $target = document.getElementById(target);
=======
// Para menú en móviles; cfr: https://bulma.io/documentation/components/navbar/#navbar-burger
=======
>>>>>>> 098cb26 (Adición de ficha por peli)
document.addEventListener('DOMContentLoaded', () => {
// Get all "navbar-burger" elements
modMenu();
});
// Habilita el menú de hamburguesa y que esté fijo
function modMenu() {
document.getElementById('nav').classList.add('is-fixed-top');
document.getElementById('menu').classList.remove('force-display');
// Cfr: https://bulma.io/documentation/components/navbar/#navbar-burger
const $navbarBurgers = Array.prototype.slice.call(document.querySelectorAll('.navbar-burger'), 0);
// Add a click event on each of them
$navbarBurgers.forEach( el => {
el.addEventListener('click', () => {
// Get the target from the "data-target" attribute
const target = el.dataset.target;
const $target = document.getElementById(target);
<<<<<<< HEAD
// Toggle the "is-active" class on both the "navbar-burger" and the "navbar-menu"
>>>>>>> fb23014 (Inicio de diseño)
=======
>>>>>>> 098cb26 (Adición de ficha por peli)
el.classList.toggle('is-active');
$target.classList.toggle('is-active');
});
});
<<<<<<< HEAD
<<<<<<< HEAD
}
=======
});
>>>>>>> fb23014 (Inicio de diseño)
=======
}
>>>>>>> 098cb26 (Adición de ficha por peli)

View File

@ -18,6 +18,7 @@ def search(request):
return render(request, "search.html", context)
<<<<<<< HEAD
def about(request):
context = {}
return render(request, "about.html", context)
@ -53,3 +54,8 @@ def search(request):
=======
return render(request, "search.html", context)
>>>>>>> a468c37 (Aplicación de 'black')
=======
def movie(request, id):
context = {"movie": Movie.objects.get_movie(id)}
return render(request, "movie.html", context)
>>>>>>> 098cb26 (Adición de ficha por peli)

View File

@ -39,6 +39,7 @@ urlpatterns = [
path("", views.home, name="home"),
path("search/", views.search, name="search"),
# path('movies/<str:args>', views.movies, name='movies'),
path("movie/<int:id>", views.movie, name="movie"),
path("ultimas/rss/", LatestMoviesFeed()),
path("admin/", admin.site.urls),
# path('api/', include(v1_api.urls)),

View File

@ -31,45 +31,11 @@
=======
</div>
</section>
<nav class="navbar is-fixed-top" role="navigation" aria-label="main navigation">
<div class="navbar-brand">
<a class="navbar-item" href="{% url 'home' %}">
<img src="{% static 'img/logo-mauflix.png' %}" width="112" height="28">
</a>
<a role="button" class="navbar-burger" aria-label="menu" aria-expanded="false" data-target="menu">
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>
</div>
<div id="menu" class="navbar-menu">
<div class="navbar-start">
{% if request.get_full_path == "/" %}
<a class="navbar-item" href="{% url 'search' %}">Buscar</a>
{% else %}
<a class="navbar-item" href="{% url 'home' %}">Inicio</a>
{% endif %}
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link">Más</a>
<div class="navbar-dropdown">
<a class="navbar-item">Acerca</a>
<hr class="navbar-divider">
<a class="navbar-item">Reporta un problema</a>
</div>
</div>
</div>
<div class="navbar-end">
<div class="navbar-item">
<div class="buttons">
<a class="button is-primary">Ingresa</a>
</div>
</div>
</div>
</div>
</nav>
{% include 'nav.html' %}
<section id="main">
{% block content %}{% endblock %}
</section>
<<<<<<< HEAD
<footer class="footer">
<div class="content">
<p><b>BCH</b>:&nbsp;<code>qztd3l00xle5tffdqvh2snvadkuau2ml0uqm4n875d</code></p>
@ -90,5 +56,8 @@
</div>
</footer>
>>>>>>> fb23014 (Inicio de diseño)
=======
{% include 'footer.html' %}
>>>>>>> 098cb26 (Adición de ficha por peli)
</body>
</html>

View File

@ -1,5 +1,38 @@
<<<<<<< HEAD
<section class="hero {% if request.get_full_path == "/" %}is-primary full{% else %}is-large{% endif%}">
{% include 'info-head.html' with movie=movie %}
{% include 'info-body.html' with movie=movie %}
{% include 'info-foot.html' with movie=movie %}
</section>
=======
<section class="hero {% if request.get_full_path == "/" %}is-fullheight{% else %}is-large{% endif%}">
<div class="hero-head movie-head">
<p class="title">{{ movie.name }}</p>
<p class="stats">
<span>{{ movie.duration }} min</span>
<span>{{ movie.count_formatted }} descargas</span>
<span class="stars">{{ movie.stars_icons }}</span>
</p>
</div>
<div class="hero-body movie-body">
<video controls>
<source src="{{ movie.file_name }}" type="video/mp4">
</video>
</div>
<div class="hero-foot">
<nav class="tabs is-boxed is-fullwidth">
<div class="container">
<ul>
<li><a href="{{ movie.file_name }}" target="_blank" download>Descargar</a></li>
{% if request.get_full_path == "/" %}
<li><a href="/movie/{{ movie.id }}">Detalles</a></li>
{% endif %}
</ul>
</div>
</nav>
</div>
</section>
{% if request.get_full_path != "/" %}
TODO: {{ movie }}
{% endif %}
>>>>>>> 098cb26 (Adición de ficha por peli)

View File

@ -12,25 +12,42 @@
</div>
<div id="menu" class="navbar-menu force-display">
<div class="navbar-start">
<<<<<<< HEAD
{% if request.get_full_path != "/" %}
<a class="navbar-item" href="{% url 'home' %}">Inicio</a>
{% endif %}
{% if request.get_full_path != "/search/" %}
<a class="navbar-item" href="{% url 'search' %}">Buscar</a>
=======
{% if request.get_full_path == "/" %}
<a class="navbar-item" href="{% url 'search' %}">Buscar</a>
{% else %}
<a class="navbar-item" href="{% url 'home' %}">Inicio</a>
>>>>>>> 098cb26 (Adición de ficha por peli)
{% endif %}
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link">Más</a>
<div class="navbar-dropdown">
<<<<<<< HEAD
<a class="navbar-item" href="{% url 'about' %}" >Acerca</a>
<hr class="navbar-divider">
<a class="navbar-item" href="{% url 'bugs' %}">Reporta un problema</a>
=======
<a class="navbar-item">Acerca</a>
<hr class="navbar-divider">
<a class="navbar-item">Reporta un problema</a>
>>>>>>> 098cb26 (Adición de ficha por peli)
</div>
</div>
</div>
<div class="navbar-end">
<div class="navbar-item">
<div class="buttons">
<<<<<<< HEAD
<a class="button is-primary" href="{% url 'admin:index' %}">Ingresa</a>
=======
<a class="button is-primary">Ingresa</a>
>>>>>>> 098cb26 (Adición de ficha por peli)
</div>
</div>
</div>

View File

@ -1,4 +1,5 @@
<section class="hero">
<<<<<<< HEAD
<<<<<<< HEAD
<div class="hero-body hero-cartels">
{% if request.get_full_path == "/" %}
@ -20,13 +21,28 @@
<div class="hero-body">
<p class="title">{{ section }}</p>
<div class="columns is-desktop">
=======
<div class="hero-body hero-cartels">
<p class="title"><a href="movies/{{ section }}">{{ section }}<span class="arrows"/></a></p>
<div class="cartels">
>>>>>>> 098cb26 (Adición de ficha por peli)
{% for movie in content %}
<div class="column">
<figure class="image is-3by4">
<img src="../media/{{ movie.cartel }}">
<div class="cartel">
<input type="checkbox" class="toggle">
<label for="checkbox">×</label>
<div class="info-container">
<div class="info">
{% include 'info.html' with movie=movie %}
</div>
</div>
<figure class="image is-2by3">
<img src="{{ movie.cartel }}">
</figure>
<<<<<<< HEAD
{{ movie }}
>>>>>>> fb23014 (Inicio de diseño)
=======
>>>>>>> 098cb26 (Adición de ficha por peli)
</div>
{% endfor %}
</div>