Ahí viene el nuevo frontend #1
|
@ -5,3 +5,5 @@ psycopg2-binary
|
|||
httpx
|
||||
django-tastypie
|
||||
django-admin-list-filter-dropdown
|
||||
wikipedia-api
|
||||
bs4
|
||||
|
|
|
@ -18,6 +18,7 @@ def run_in_thread(fn):
|
|||
t = threading.Thread(target=fn, args=k, kwargs=kw)
|
||||
t.start()
|
||||
return t
|
||||
|
||||
return run
|
||||
|
||||
|
||||
|
@ -25,35 +26,30 @@ def run_in_thread(fn):
|
|||
class AdminPerson(admin.ModelAdmin):
|
||||
list_per_page = 50
|
||||
list_display = (
|
||||
'name',
|
||||
'country',
|
||||
'is_actor',
|
||||
'is_director',
|
||||
'is_woman',
|
||||
"name",
|
||||
"country",
|
||||
"is_actor",
|
||||
"is_director",
|
||||
"is_woman",
|
||||
)
|
||||
search_fields = ('name',)
|
||||
list_filter = ('is_woman', 'is_actor', 'is_director', 'country')
|
||||
search_fields = ("name",)
|
||||
list_filter = ("is_woman", "is_actor", "is_director", "country")
|
||||
|
||||
|
||||
@admin.register(models.Movie)
|
||||
class AdminMovie(admin.ModelAdmin):
|
||||
list_per_page = 50
|
||||
list_display = (
|
||||
'name',
|
||||
'original_name',
|
||||
'year',
|
||||
'duration',
|
||||
'count')
|
||||
search_fields = ('name', 'original_name')
|
||||
filter_horizontal = ('directors',)
|
||||
list_display = ("name", "original_name", "year", "duration", "count")
|
||||
search_fields = ("name", "original_name")
|
||||
filter_horizontal = ("directors",)
|
||||
list_filter = (
|
||||
'is_digital',
|
||||
('directors__name', DropdownFilter),
|
||||
('countries__name', DropdownFilter),
|
||||
('year', DropdownFilter),
|
||||
)
|
||||
"is_digital",
|
||||
("directors__name", DropdownFilter),
|
||||
("countries__name", DropdownFilter),
|
||||
("year", DropdownFilter),
|
||||
)
|
||||
_is_new = False
|
||||
actions = ['published']
|
||||
actions = ["published"]
|
||||
|
||||
def save_model(self, request, obj, form, change):
|
||||
self._is_new = obj.pk is None
|
||||
|
@ -68,30 +64,32 @@ class AdminMovie(admin.ModelAdmin):
|
|||
return
|
||||
|
||||
def formfield_for_manytomany(self, db_field, request, **kwargs):
|
||||
if db_field.name == 'directors':
|
||||
kwargs['queryset'] = models.Person.objects.filter(is_director=True)
|
||||
if db_field.name == 'actors':
|
||||
kwargs['queryset'] = models.Person.objects.filter(is_actor=True)
|
||||
if db_field.name == "directors":
|
||||
kwargs["queryset"] = models.Person.objects.filter(is_director=True)
|
||||
if db_field.name == "actors":
|
||||
kwargs["queryset"] = models.Person.objects.filter(is_actor=True)
|
||||
return super().formfield_for_manytomany(db_field, request, **kwargs)
|
||||
|
||||
def published(self, request, queryset):
|
||||
obj = queryset[0]
|
||||
self._public(obj)
|
||||
self.message_user(request, 'Publicado correctamente', messages.SUCCESS)
|
||||
published.short_description = 'Republicar en redes'
|
||||
self.message_user(request, "Publicado correctamente", messages.SUCCESS)
|
||||
|
||||
published.short_description = "Republicar en redes"
|
||||
|
||||
def _public_mastodon(self, message, cartel):
|
||||
MT = {
|
||||
'jpg': 'image/jpeg',
|
||||
'png': 'image/png',
|
||||
"jpg": "image/jpeg",
|
||||
"png": "image/png",
|
||||
}
|
||||
message += '\n\n#mauflix'
|
||||
message += "\n\n#mauflix"
|
||||
media_type = MT[cartel.url[-3:]]
|
||||
|
||||
try:
|
||||
server = Mastodon(
|
||||
access_token=settings.TOKEN_MASTODON,
|
||||
api_base_url=settings.URL_MASTODON)
|
||||
api_base_url=settings.URL_MASTODON,
|
||||
)
|
||||
|
||||
media = server.media_post(cartel.read(), media_type)
|
||||
server.status_post(message, media_ids=media)
|
||||
|
@ -100,9 +98,13 @@ class AdminMovie(admin.ModelAdmin):
|
|||
return
|
||||
|
||||
def _public_telegram(self, message, cartel):
|
||||
url = f'https://api.telegram.org/bot{settings.TOKEN_TELEGRAM}/sendPhoto'
|
||||
url = f"https://api.telegram.org/bot{settings.TOKEN_TELEGRAM}/sendPhoto"
|
||||
url_cartel = settings.URL_CDN.format(cartel)
|
||||
data = {'chat_id': settings.CHAT_ID, 'photo': url_cartel, 'caption': message}
|
||||
data = {
|
||||
"chat_id": settings.CHAT_ID,
|
||||
"photo": url_cartel,
|
||||
"caption": message,
|
||||
}
|
||||
result = httpx.post(url, data=data).json()
|
||||
return
|
||||
|
||||
|
@ -121,4 +123,3 @@ Año: {obj.year}
|
|||
|
||||
admin.site.register(models.Gender)
|
||||
admin.site.register(models.Country)
|
||||
|
||||
|
|
|
@ -16,64 +16,61 @@ from django.conf import settings
|
|||
|
||||
|
||||
class CustomAuthentication(Authentication):
|
||||
|
||||
def is_authenticated(self, request, **kwargs):
|
||||
if not 'ApiToken' in request.headers:
|
||||
if not "ApiToken" in request.headers:
|
||||
return False
|
||||
|
||||
if request.headers['ApiToken'] != settings.API_TOKEN:
|
||||
if request.headers["ApiToken"] != settings.API_TOKEN:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
class ResourceDirectors(ModelResource):
|
||||
|
||||
class Meta:
|
||||
queryset = Person.objects.all().filter(is_director=True)
|
||||
resource_name = 'directors'
|
||||
resource_name = "directors"
|
||||
|
||||
|
||||
class ResourceCountries(ModelResource):
|
||||
|
||||
class Meta:
|
||||
queryset = Country.objects.all()
|
||||
resource_name = 'countries'
|
||||
resource_name = "countries"
|
||||
|
||||
|
||||
class ResourceMovies(ModelResource):
|
||||
directors = fields.ToManyField(ResourceDirectors, 'directors', full=True)
|
||||
countries = fields.ToManyField(ResourceCountries, 'countries', full=True)
|
||||
directors = fields.ToManyField(ResourceDirectors, "directors", full=True)
|
||||
countries = fields.ToManyField(ResourceCountries, "countries", full=True)
|
||||
|
||||
class Meta:
|
||||
queryset = Movie.objects.all().order_by('-id')
|
||||
resource_name = 'movies'
|
||||
excludes = ['count', 'duration', 'published', 'stars']
|
||||
queryset = Movie.objects.all().order_by("-id")
|
||||
resource_name = "movies"
|
||||
excludes = ["count", "duration", "published", "stars"]
|
||||
throttle = BaseThrottle(throttle_at=50)
|
||||
allowed_methods = ['get']
|
||||
allowed_methods = ["get"]
|
||||
authentication = CustomAuthentication()
|
||||
limit = 10
|
||||
max_limit = 10
|
||||
filtering = {
|
||||
'name': ALL,
|
||||
'original_name': ALL,
|
||||
"name": ALL,
|
||||
"original_name": ALL,
|
||||
}
|
||||
|
||||
def dehydrate_directors(self, bundle):
|
||||
names = ', '.join([d.obj.name for d in bundle.data['directors']])
|
||||
names = ", ".join([d.obj.name for d in bundle.data["directors"]])
|
||||
return names
|
||||
|
||||
def dehydrate_countries(self, bundle):
|
||||
names = ', '.join([c.obj.name for c in bundle.data['countries']])
|
||||
names = ", ".join([c.obj.name for c in bundle.data["countries"]])
|
||||
return names
|
||||
|
||||
# ~ def build_filters(self, filters=None, **kwargs):
|
||||
# ~ orm_filters = super().build_filters(filters or {}, **kwargs)
|
||||
# ~ return orm_filters
|
||||
# ~ orm_filters = super().build_filters(filters or {}, **kwargs)
|
||||
# ~ return orm_filters
|
||||
|
||||
def apply_filters(self, request, applicable_filters):
|
||||
objects = self.get_object_list(request)
|
||||
query = applicable_filters['name__icontains']
|
||||
qset = (Q(name__icontains=query) | Q(original_name__icontains=query))
|
||||
query = applicable_filters["name__icontains"]
|
||||
qset = Q(name__icontains=query) | Q(original_name__icontains=query)
|
||||
objects = objects.filter(qset)
|
||||
return objects
|
||||
|
|
|
@ -2,4 +2,4 @@ from django.apps import AppConfig
|
|||
|
||||
|
||||
class MainConfig(AppConfig):
|
||||
name = 'main'
|
||||
name = "main"
|
||||
|
|
|
@ -6,12 +6,12 @@ from .models import Movie
|
|||
|
||||
|
||||
class LatestMoviesFeed(Feed):
|
||||
title = 'Lo ultimo en MauFlix'
|
||||
link = ''
|
||||
description = 'Ultimas diez películas disponibles en MauFlix'
|
||||
title = "Lo ultimo en MauFlix"
|
||||
link = ""
|
||||
description = "Ultimas diez películas disponibles en MauFlix"
|
||||
|
||||
def items(self):
|
||||
return Movie.objects.order_by('-id')[:10]
|
||||
return Movie.objects.order_by("-id")[:10]
|
||||
|
||||
def item_title(self, item):
|
||||
return item.name
|
||||
|
@ -21,4 +21,4 @@ class LatestMoviesFeed(Feed):
|
|||
return message
|
||||
|
||||
def item_link(self, item):
|
||||
return reverse('movies', args=[item.pk])
|
||||
return reverse("movies", args=[item.pk])
|
||||
|
|
|
@ -8,76 +8,218 @@ class Migration(migrations.Migration):
|
|||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
dependencies = []
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Country',
|
||||
name="Country",
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=250)),
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("name", models.CharField(max_length=250)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'País',
|
||||
'verbose_name_plural': 'Paises',
|
||||
'ordering': ['name'],
|
||||
'unique_together': {('name',)},
|
||||
"verbose_name": "País",
|
||||
"verbose_name_plural": "Paises",
|
||||
"ordering": ["name"],
|
||||
"unique_together": {("name",)},
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Gender',
|
||||
name="Gender",
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=250)),
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("name", models.CharField(max_length=250)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Género',
|
||||
'verbose_name_plural': 'Generos',
|
||||
'ordering': ['name'],
|
||||
'unique_together': {('name',)},
|
||||
"verbose_name": "Género",
|
||||
"verbose_name_plural": "Generos",
|
||||
"ordering": ["name"],
|
||||
"unique_together": {("name",)},
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Person',
|
||||
name="Person",
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=500, verbose_name='Nombre')),
|
||||
('date_born', models.DateField(blank=True, null=True, verbose_name='Fecha de nacimiento')),
|
||||
('is_actor', models.BooleanField(default=False, verbose_name='Es Actor')),
|
||||
('is_director', models.BooleanField(default=False, verbose_name='Es Director')),
|
||||
('photo', models.ImageField(blank=True, null=True, upload_to='%Y/%m/%d/', verbose_name='Fotografía')),
|
||||
('country', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='country', to='main.Country')),
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"name",
|
||||
models.CharField(max_length=500, verbose_name="Nombre"),
|
||||
),
|
||||
(
|
||||
"date_born",
|
||||
models.DateField(
|
||||
blank=True,
|
||||
null=True,
|
||||
verbose_name="Fecha de nacimiento",
|
||||
),
|
||||
),
|
||||
(
|
||||
"is_actor",
|
||||
models.BooleanField(default=False, verbose_name="Es Actor"),
|
||||
),
|
||||
(
|
||||
"is_director",
|
||||
models.BooleanField(
|
||||
default=False, verbose_name="Es Director"
|
||||
),
|
||||
),
|
||||
(
|
||||
"photo",
|
||||
models.ImageField(
|
||||
blank=True,
|
||||
null=True,
|
||||
upload_to="%Y/%m/%d/",
|
||||
verbose_name="Fotografía",
|
||||
),
|
||||
),
|
||||
(
|
||||
"country",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.PROTECT,
|
||||
related_name="country",
|
||||
to="main.Country",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Persona',
|
||||
'verbose_name_plural': 'Personas',
|
||||
'ordering': ['name'],
|
||||
'unique_together': {('name',)},
|
||||
"verbose_name": "Persona",
|
||||
"verbose_name_plural": "Personas",
|
||||
"ordering": ["name"],
|
||||
"unique_together": {("name",)},
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Movie',
|
||||
name="Movie",
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=1000, verbose_name='Nombre')),
|
||||
('original_name', models.CharField(blank=True, default='', max_length=1000, verbose_name='Nombre original')),
|
||||
('file_name', models.CharField(blank=True, default='', max_length=1000, verbose_name='Nombre archivo')),
|
||||
('year', models.PositiveSmallIntegerField(default=1900, verbose_name='Año')),
|
||||
('duration', models.PositiveSmallIntegerField(default=0, verbose_name='Duración')),
|
||||
('cartel', models.ImageField(blank=True, null=True, upload_to='%Y/%m/%d/', verbose_name='Cartel')),
|
||||
('count', models.PositiveIntegerField(default=0, verbose_name='Descargas')),
|
||||
('stars', models.PositiveSmallIntegerField(default=0, verbose_name='Estrellas')),
|
||||
('actors', models.ManyToManyField(blank=True, related_name='actors', to='main.Person', verbose_name='Reparto')),
|
||||
('countries', models.ManyToManyField(blank=True, related_name='countries', to='main.Country', verbose_name='País')),
|
||||
('directors', models.ManyToManyField(related_name='directors', to='main.Person', verbose_name='Director')),
|
||||
('genders', models.ManyToManyField(blank=True, related_name='genders', to='main.Gender', verbose_name='Género')),
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"name",
|
||||
models.CharField(max_length=1000, verbose_name="Nombre"),
|
||||
),
|
||||
(
|
||||
"original_name",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default="",
|
||||
max_length=1000,
|
||||
verbose_name="Nombre original",
|
||||
),
|
||||
),
|
||||
(
|
||||
"file_name",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default="",
|
||||
max_length=1000,
|
||||
verbose_name="Nombre archivo",
|
||||
),
|
||||
),
|
||||
(
|
||||
"year",
|
||||
models.PositiveSmallIntegerField(
|
||||
default=1900, verbose_name="Año"
|
||||
),
|
||||
),
|
||||
(
|
||||
"duration",
|
||||
models.PositiveSmallIntegerField(
|
||||
default=0, verbose_name="Duración"
|
||||
),
|
||||
),
|
||||
(
|
||||
"cartel",
|
||||
models.ImageField(
|
||||
blank=True,
|
||||
null=True,
|
||||
upload_to="%Y/%m/%d/",
|
||||
verbose_name="Cartel",
|
||||
),
|
||||
),
|
||||
(
|
||||
"count",
|
||||
models.PositiveIntegerField(
|
||||
default=0, verbose_name="Descargas"
|
||||
),
|
||||
),
|
||||
(
|
||||
"stars",
|
||||
models.PositiveSmallIntegerField(
|
||||
default=0, verbose_name="Estrellas"
|
||||
),
|
||||
),
|
||||
(
|
||||
"actors",
|
||||
models.ManyToManyField(
|
||||
blank=True,
|
||||
related_name="actors",
|
||||
to="main.Person",
|
||||
verbose_name="Reparto",
|
||||
),
|
||||
),
|
||||
(
|
||||
"countries",
|
||||
models.ManyToManyField(
|
||||
blank=True,
|
||||
related_name="countries",
|
||||
to="main.Country",
|
||||
verbose_name="País",
|
||||
),
|
||||
),
|
||||
(
|
||||
"directors",
|
||||
models.ManyToManyField(
|
||||
related_name="directors",
|
||||
to="main.Person",
|
||||
verbose_name="Director",
|
||||
),
|
||||
),
|
||||
(
|
||||
"genders",
|
||||
models.ManyToManyField(
|
||||
blank=True,
|
||||
related_name="genders",
|
||||
to="main.Gender",
|
||||
verbose_name="Género",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Película',
|
||||
'verbose_name_plural': 'Películas',
|
||||
'ordering': ['name'],
|
||||
'unique_together': {('name', 'original_name')},
|
||||
"verbose_name": "Película",
|
||||
"verbose_name_plural": "Películas",
|
||||
"ordering": ["name"],
|
||||
"unique_together": {("name", "original_name")},
|
||||
},
|
||||
),
|
||||
]
|
||||
|
|
|
@ -7,18 +7,23 @@ import main.models
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('main', '0001_initial'),
|
||||
("main", "0001_initial"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='movie',
|
||||
name='published',
|
||||
field=models.BooleanField(default=True, verbose_name='¿Publicar?'),
|
||||
model_name="movie",
|
||||
name="published",
|
||||
field=models.BooleanField(default=True, verbose_name="¿Publicar?"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='movie',
|
||||
name='cartel',
|
||||
field=models.ImageField(blank=True, null=True, upload_to=main.models.upload_cartel, verbose_name='Cartel'),
|
||||
model_name="movie",
|
||||
name="cartel",
|
||||
field=models.ImageField(
|
||||
blank=True,
|
||||
null=True,
|
||||
upload_to=main.models.upload_cartel,
|
||||
verbose_name="Cartel",
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -6,13 +6,13 @@ from django.db import migrations, models
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('main', '0002_auto_20200602_2302'),
|
||||
("main", "0002_auto_20200602_2302"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='movie',
|
||||
name='is_digital',
|
||||
field=models.BooleanField(default=False, verbose_name='Es digital'),
|
||||
model_name="movie",
|
||||
name="is_digital",
|
||||
field=models.BooleanField(default=False, verbose_name="Es digital"),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -6,23 +6,25 @@ from django.db import migrations, models
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('main', '0003_movie_is_digital'),
|
||||
("main", "0003_movie_is_digital"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='person',
|
||||
name='is_woman',
|
||||
field=models.BooleanField(default=False, verbose_name='Es mujer'),
|
||||
model_name="person",
|
||||
name="is_woman",
|
||||
field=models.BooleanField(default=False, verbose_name="Es mujer"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='country',
|
||||
name='name',
|
||||
field=models.CharField(max_length=250, verbose_name='País'),
|
||||
model_name="country",
|
||||
name="name",
|
||||
field=models.CharField(max_length=250, verbose_name="País"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='movie',
|
||||
name='actors',
|
||||
field=models.ManyToManyField(blank=True, related_name='actors', to='main.Person'),
|
||||
model_name="movie",
|
||||
name="actors",
|
||||
field=models.ManyToManyField(
|
||||
blank=True, related_name="actors", to="main.Person"
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
|
||||
import requests
|
||||
import shutil
|
||||
import random
|
||||
import time
|
||||
import wikipediaapi
|
||||
from bs4 import BeautifulSoup
|
||||
from django.conf import settings
|
||||
from django.db import models
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
class Gender(models.Model):
|
||||
|
@ -8,10 +14,10 @@ class Gender(models.Model):
|
|||
name = models.CharField(max_length=250)
|
||||
|
||||
class Meta:
|
||||
unique_together = ['name']
|
||||
ordering = ['name']
|
||||
verbose_name = 'Género'
|
||||
verbose_name_plural = 'Generos'
|
||||
unique_together = ["name"]
|
||||
ordering = ["name"]
|
||||
verbose_name = "Género"
|
||||
verbose_name_plural = "Generos"
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
@ -19,162 +25,212 @@ class Gender(models.Model):
|
|||
|
||||
class Country(models.Model):
|
||||
id = models.AutoField(primary_key=True)
|
||||
name = models.CharField(max_length=250, verbose_name='País')
|
||||
name = models.CharField(max_length=250, verbose_name="País")
|
||||
|
||||
class Meta:
|
||||
unique_together = ['name']
|
||||
ordering = ['name']
|
||||
verbose_name = 'País'
|
||||
verbose_name_plural = 'Paises'
|
||||
unique_together = ["name"]
|
||||
ordering = ["name"]
|
||||
verbose_name = "País"
|
||||
verbose_name_plural = "Paises"
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
class PersonQuerySet(models.QuerySet):
|
||||
|
||||
def directors(self):
|
||||
rows = self.filter(is_director=True).values_list('name', flat=True)
|
||||
rows = self.filter(is_director=True).values_list("name", flat=True)
|
||||
return rows
|
||||
|
||||
def actors(self):
|
||||
rows = self.filter(is_actor=True).values_list('name', flat=True)
|
||||
rows = self.filter(is_actor=True).values_list("name", flat=True)
|
||||
return rows
|
||||
|
||||
|
||||
class Person(models.Model):
|
||||
id = models.AutoField(primary_key=True)
|
||||
name = models.CharField('Nombre',
|
||||
max_length=500)
|
||||
country = models.ForeignKey(Country,
|
||||
related_name='country', on_delete=models.PROTECT)
|
||||
date_born = models.DateField('Fecha de nacimiento',
|
||||
null=True, blank=True)
|
||||
is_actor = models.BooleanField('Es Actor',
|
||||
default=False)
|
||||
is_director = models.BooleanField('Es Director',
|
||||
default=False)
|
||||
is_woman = models.BooleanField('Es mujer',
|
||||
default=False)
|
||||
photo = models.ImageField('Fotografía', upload_to='%Y/%m/%d/',
|
||||
null=True, blank=True)
|
||||
name = models.CharField("Nombre", max_length=500)
|
||||
country = models.ForeignKey(
|
||||
Country, related_name="country", on_delete=models.PROTECT
|
||||
)
|
||||
date_born = models.DateField("Fecha de nacimiento", null=True, blank=True)
|
||||
is_actor = models.BooleanField("Es Actor", default=False)
|
||||
is_director = models.BooleanField("Es Director", default=False)
|
||||
is_woman = models.BooleanField("Es mujer", default=False)
|
||||
photo = models.ImageField(
|
||||
"Fotografía", upload_to="%Y/%m/%d/", null=True, blank=True
|
||||
)
|
||||
objects = PersonQuerySet.as_manager()
|
||||
|
||||
class Meta:
|
||||
unique_together = ['name']
|
||||
ordering = ['name']
|
||||
verbose_name = 'Persona'
|
||||
verbose_name_plural = 'Personas'
|
||||
unique_together = ["name"]
|
||||
ordering = ["name"]
|
||||
verbose_name = "Persona"
|
||||
verbose_name_plural = "Personas"
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
class MovieQuerySet(models.QuerySet):
|
||||
|
||||
def _to_str(self, q):
|
||||
return ','.join([r.name for r in q.all()])
|
||||
|
||||
def _to_link(self, file_name):
|
||||
# ~ folder = file_name[0].upper()
|
||||
# ~ if folder.isdigit():
|
||||
# ~ folder = '0'
|
||||
url = settings.URL_CDN.format(file_name)
|
||||
return url
|
||||
|
||||
def _to_image(self, img, director=''):
|
||||
data = ''
|
||||
if img:
|
||||
url = '../'
|
||||
if director:
|
||||
url = '../../'
|
||||
data = url + img.url
|
||||
return data
|
||||
|
||||
def to_dict(self, query='', director='', id=0):
|
||||
rows = self.all().order_by('-id')[:10]
|
||||
if query == 'all':
|
||||
rows = self.all()
|
||||
elif id:
|
||||
rows = self.filter(id=id)
|
||||
director = ' '
|
||||
def random_pick(self, random_max=6, min_items=20, **kwargs):
|
||||
all = list(Movie.objects.filter(**kwargs).values())
|
||||
if len(all) < min_items:
|
||||
return None
|
||||
elif len(all) < random_max:
|
||||
return all
|
||||
else:
|
||||
if director:
|
||||
rows = self.filter(directors__name__iexact=director)
|
||||
elif query:
|
||||
rows = self.filter(name__icontains=query)
|
||||
return random.sample(all, random_max)
|
||||
|
||||
movies = []
|
||||
for row in rows:
|
||||
data = {}
|
||||
data['id'] = row.id
|
||||
data['url'] = self._to_link(row.file_name)
|
||||
data['name'] = row.name
|
||||
data['year'] = row.year
|
||||
data['original_name'] = row.original_name
|
||||
data['duration'] = row.duration
|
||||
data['director'] = self._to_str(row.directors)
|
||||
data['country'] = self._to_str(row.countries)
|
||||
data['count'] = row.count
|
||||
data['image'] = self._to_image(row.cartel, director)
|
||||
movies.append(data)
|
||||
def top_pick(self, key, top_max=6):
|
||||
all = list(Movie.objects.order_by(f"-{key}").values())
|
||||
return all[:top_max]
|
||||
|
||||
matrix = []
|
||||
for i in range (0, len(movies), 4):
|
||||
matrix.append(movies[i:i+4])
|
||||
return matrix
|
||||
def top_random_pick(self, key, top_max=6):
|
||||
all = list(Movie.objects.order_by(f"-{key}").values())
|
||||
top = []
|
||||
for movie in all:
|
||||
if movie[key] == all[0][key]:
|
||||
top.append(movie)
|
||||
else:
|
||||
break
|
||||
if len(top) > top_max:
|
||||
return random.sample(top, top_max)
|
||||
else:
|
||||
return top
|
||||
|
||||
def get_directors(self):
|
||||
data = self.distinct().values_list(
|
||||
'directors__name', flat=True).order_by('directors')
|
||||
return data
|
||||
def home_pick(self):
|
||||
genders = list(Gender.objects.values_list("id", flat=True))
|
||||
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] = self.fix_all_data(picked)
|
||||
return sections
|
||||
|
||||
def home_sections(self):
|
||||
sections = {
|
||||
"Novedades": self.fix_all_data(self.top_pick("id")),
|
||||
"Mejor valorados": self.fix_all_data(self.top_random_pick("stars")),
|
||||
"Más descargados": self.fix_all_data(self.top_pick("count")),
|
||||
}
|
||||
sections["genders"] = {}
|
||||
return sections
|
||||
|
||||
def fix_all_data(self, movies):
|
||||
for movie in movies:
|
||||
self.fix_data(movie, wikipedia=False)
|
||||
return movies
|
||||
|
||||
def fix_data(self, movie, wikipedia=True):
|
||||
movie["duration_formatted"] = self.format_duration(movie["duration"])
|
||||
movie["count_formatted"] = self.format_count(movie["count"])
|
||||
movie["stars_icons"] = self.format_stars(movie["stars"])
|
||||
movie["file_name"] = self.fix_path(movie["file_name"])
|
||||
movie["cartel"] = self.fix_path(movie["cartel"])
|
||||
if wikipedia:
|
||||
movie["wiki"] = self.get_wiki(movie)
|
||||
|
||||
def fix_path(self, el):
|
||||
if settings.DEBUG:
|
||||
return settings.URL_CDN.format(el)
|
||||
else:
|
||||
return settings.MEDIA_ROOT / el
|
||||
|
||||
def fix_summ(self, raw):
|
||||
html = BeautifulSoup(raw, "lxml")
|
||||
for ref in html.find_all("sup", "reference"):
|
||||
ref.decompose()
|
||||
clean = list(map(lambda x: str(x), html.body.children))
|
||||
return " ".join(clean)
|
||||
|
||||
def format_stars(self, num):
|
||||
stars = "★" * num
|
||||
while len(stars) < 5:
|
||||
stars += "☆"
|
||||
return stars
|
||||
|
||||
def format_count(self, num):
|
||||
return "{:,}".format(num)
|
||||
|
||||
def format_duration(self, num):
|
||||
secs = num * 60
|
||||
return time.strftime("%H:%M", time.gmtime(secs))
|
||||
|
||||
def get_wiki(self, movie, again=True):
|
||||
wiki = self.get_wiki_page(movie["original_name"])
|
||||
if not wiki:
|
||||
wiki = self.get_wiki_page(movie["name"])
|
||||
return wiki
|
||||
|
||||
def get_wiki_page(self, title):
|
||||
try:
|
||||
lang = settings.LANGUAGE_CODE.split("-")[0]
|
||||
wiki = wikipediaapi.Wikipedia(
|
||||
lang, extract_format=wikipediaapi.ExtractFormat.HTML
|
||||
)
|
||||
page = wiki.page(title)
|
||||
if page.exists():
|
||||
return {
|
||||
"title": page.title,
|
||||
"url": page.fullurl,
|
||||
"summary": self.fix_summ(page.summary),
|
||||
}
|
||||
else:
|
||||
return None
|
||||
except:
|
||||
return None
|
||||
|
||||
def get_movie(self, id):
|
||||
movie = Movie.objects.select_related().get(pk=id).__dict__
|
||||
movie.pop("_state")
|
||||
self.fix_data(movie)
|
||||
return movie
|
||||
|
||||
|
||||
def upload_cartel(instance, filename):
|
||||
first = filename[0].upper()
|
||||
if first.isdigit():
|
||||
first = '0'
|
||||
return f'{first}/{filename}'
|
||||
first = "0"
|
||||
return f"{first}/{filename}"
|
||||
|
||||
|
||||
class Movie(models.Model):
|
||||
id = models.AutoField(primary_key=True)
|
||||
name = models.CharField('Nombre',
|
||||
max_length=1000)
|
||||
original_name = models.CharField('Nombre original',
|
||||
max_length=1000, default='', blank=True)
|
||||
file_name = models.CharField('Nombre archivo',
|
||||
max_length=1000, default='', blank=True)
|
||||
year = models.PositiveSmallIntegerField('Año',
|
||||
default=1900)
|
||||
duration = models.PositiveSmallIntegerField('Duración',
|
||||
default=0)
|
||||
directors = models.ManyToManyField(Person, verbose_name='Director',
|
||||
related_name='directors')
|
||||
actors = models.ManyToManyField(Person,
|
||||
related_name='actors', blank=True)
|
||||
countries = models.ManyToManyField(Country,
|
||||
related_name='countries', verbose_name='País', blank=True)
|
||||
genders = models.ManyToManyField(Gender,
|
||||
related_name='genders', verbose_name='Género', blank=True)
|
||||
cartel = models.ImageField('Cartel', upload_to=upload_cartel,
|
||||
null=True, blank=True)
|
||||
count = models.PositiveIntegerField('Descargas',
|
||||
default=0)
|
||||
stars = models.PositiveSmallIntegerField('Estrellas',
|
||||
default=0)
|
||||
published = models.BooleanField('¿Publicar?',
|
||||
default=True)
|
||||
is_digital = models.BooleanField('Es digital',
|
||||
default=False)
|
||||
name = models.CharField("Nombre", max_length=1000)
|
||||
original_name = models.CharField(
|
||||
"Nombre original", max_length=1000, default="", blank=True
|
||||
)
|
||||
file_name = models.CharField(
|
||||
"Nombre archivo", max_length=1000, default="", blank=True
|
||||
)
|
||||
year = models.PositiveSmallIntegerField("Año", default=1900)
|
||||
duration = models.PositiveSmallIntegerField("Duración", default=0)
|
||||
directors = models.ManyToManyField(
|
||||
Person, verbose_name="Director", related_name="directors"
|
||||
)
|
||||
actors = models.ManyToManyField(Person, related_name="actors", blank=True)
|
||||
countries = models.ManyToManyField(
|
||||
Country, related_name="countries", verbose_name="País", blank=True
|
||||
)
|
||||
genders = models.ManyToManyField(
|
||||
Gender, related_name="genders", verbose_name="Género", blank=True
|
||||
)
|
||||
cartel = models.ImageField(
|
||||
"Cartel", upload_to=upload_cartel, null=True, blank=True
|
||||
)
|
||||
count = models.PositiveIntegerField("Descargas", default=0)
|
||||
stars = models.PositiveSmallIntegerField("Estrellas", default=0)
|
||||
published = models.BooleanField("¿Publicar?", default=True)
|
||||
is_digital = models.BooleanField("Es digital", default=False)
|
||||
objects = MovieQuerySet.as_manager()
|
||||
|
||||
class Meta:
|
||||
unique_together = ['name', 'original_name']
|
||||
ordering = ['name']
|
||||
verbose_name = 'Película'
|
||||
verbose_name_plural = 'Películas'
|
||||
unique_together = ["name", "original_name"]
|
||||
ordering = ["name"]
|
||||
verbose_name = "Película"
|
||||
verbose_name_plural = "Películas"
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,321 @@
|
|||
/* BASE */
|
||||
|
||||
:root {
|
||||
--color-primary: #375a7f;
|
||||
--color-background: #343c3d;
|
||||
}
|
||||
|
||||
#nav {
|
||||
z-index: 101;
|
||||
}
|
||||
|
||||
#nav.is-fixed-top {
|
||||
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 {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 102;
|
||||
}
|
||||
|
||||
/* HOME / MOVIE */
|
||||
|
||||
/* Cada ficha de peli */
|
||||
|
||||
.movie-head {
|
||||
padding: 2rem 2rem 0 2rem !important;
|
||||
}
|
||||
|
||||
.movie-body {
|
||||
padding: 2rem !important;
|
||||
}
|
||||
|
||||
.full .movie-body {
|
||||
padding: 0 2rem !important;
|
||||
line-height: 2;
|
||||
}
|
||||
|
||||
.movie-body video {
|
||||
display: block;
|
||||
height: 100%;
|
||||
width: auto;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.info {
|
||||
background-color: var(--color-background);
|
||||
}
|
||||
|
||||
.info .full {
|
||||
height: 100%;
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
.stats span {
|
||||
padding-right: 2rem;
|
||||
}
|
||||
|
||||
.stats i {
|
||||
display: inline-block;
|
||||
margin-right: .5rem;
|
||||
}
|
||||
|
||||
.stats i.gg-time {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.stars {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.about {
|
||||
max-width: 70rem;
|
||||
margin: auto;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.about p + p {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.about *:not(h2) + h2 {
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
|
||||
.infobox td:first-child {
|
||||
text-align: right;
|
||||
width: 8rem;
|
||||
}
|
||||
|
||||
.about figure {
|
||||
width: 50%;
|
||||
height: auto;
|
||||
max-width: 300px;
|
||||
max-height: 450px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
/* 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 {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.toggle {
|
||||
position: absolute;
|
||||
z-index: 100;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.toggle:checked {
|
||||
display: block;
|
||||
z-index: 103;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
height: calc(100% - 3em);
|
||||
}
|
||||
|
||||
/* ICONS; cfr: https://css.gg */
|
||||
|
||||
.gg-time {
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
display: block;
|
||||
transform: scale(var(--ggs,1));
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
border-radius: 100%;
|
||||
border: 2px solid transparent;
|
||||
box-shadow: 0 0 0 2px currentColor;
|
||||
}
|
||||
|
||||
.gg-time::after {
|
||||
content: "";
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
position: absolute;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-left: 2px solid;
|
||||
border-bottom: 2px solid;
|
||||
top: 0;
|
||||
left: 4px;
|
||||
}
|
||||
|
||||
.gg-software-download {
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
display: block;
|
||||
transform: scale(var(--ggs,1));
|
||||
width: 16px;
|
||||
height: 6px;
|
||||
border: 2px solid;
|
||||
border-top: 0;
|
||||
border-bottom-left-radius: 2px;
|
||||
border-bottom-right-radius: 2px;
|
||||
margin-top: 8px
|
||||
}
|
||||
|
||||
.gg-software-download::after {
|
||||
content: "";
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
position: absolute;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-left: 2px solid;
|
||||
border-bottom: 2px solid;
|
||||
transform: rotate(-45deg);
|
||||
left: 2px;
|
||||
bottom: 4px
|
||||
}
|
||||
|
||||
.gg-software-download::before {
|
||||
content: "";
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
position: absolute;
|
||||
border-radius: 3px;
|
||||
width: 2px;
|
||||
height: 10px;
|
||||
background: currentColor;
|
||||
left: 5px;
|
||||
bottom: 5px
|
||||
}
|
||||
|
||||
.gg-link {
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
display: block;
|
||||
transform: rotate(-45deg) scale(var(--ggs,1));
|
||||
width: 8px;
|
||||
height: 2px;
|
||||
background: currentColor;
|
||||
border-radius: 4px
|
||||
}
|
||||
|
||||
.gg-link::after,
|
||||
.gg-link::before {
|
||||
content: "";
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
position: absolute;
|
||||
border-radius: 3px;
|
||||
width: 8px;
|
||||
height: 10px;
|
||||
border: 2px solid;
|
||||
top: -4px
|
||||
}
|
||||
|
||||
.gg-link::before {
|
||||
border-right: 0;
|
||||
border-top-left-radius: 40px;
|
||||
border-bottom-left-radius: 40px;
|
||||
left: -6px
|
||||
}
|
||||
|
||||
.gg-link::after {
|
||||
border-left: 0;
|
||||
border-top-right-radius: 40px;
|
||||
border-bottom-right-radius: 40px;
|
||||
right: -6px
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
|
@ -0,0 +1,19 @@
|
|||
document.addEventListener('DOMContentLoaded', () => {
|
||||
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);
|
||||
$navbarBurgers.forEach( el => {
|
||||
el.addEventListener('click', () => {
|
||||
const target = el.dataset.target;
|
||||
const $target = document.getElementById(target);
|
||||
el.classList.toggle('is-active');
|
||||
$target.classList.toggle('is-active');
|
||||
});
|
||||
});
|
||||
}
|
|
@ -7,58 +7,30 @@ from .models import Movie, Person
|
|||
|
||||
|
||||
def home(request):
|
||||
context = {"sections": Movie.objects.home_pick()}
|
||||
return render(request, "home.html", context)
|
||||
|
||||
|
||||
def search(request):
|
||||
context = {}
|
||||
return render(request, 'home.html', context)
|
||||
return render(request, "search.html", context)
|
||||
|
||||
|
||||
def movies(request, args=''):
|
||||
if args:
|
||||
try:
|
||||
id = int(args)
|
||||
return by_id(request, id)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
count = 0
|
||||
data = Movie.objects.to_dict(args.strip())
|
||||
directors = Person.objects.directors()
|
||||
if data:
|
||||
count = (len(data) - 1) * 4 + (len(data[-1]))
|
||||
context = {'movies': data, 'args': args, 'count': count,
|
||||
'directors': directors, 'selected_director': ''}
|
||||
return render(request, 'movies.html', context)
|
||||
def about(request):
|
||||
context = {}
|
||||
return render(request, "about.html", context)
|
||||
|
||||
|
||||
def by_id(request, id):
|
||||
count = 0
|
||||
data = Movie.objects.to_dict(id=id)
|
||||
directors = Person.objects.directors()
|
||||
if data:
|
||||
count = (len(data) - 1) * 4 + (len(data[-1]))
|
||||
context = {'movies': data, 'args': id, 'count': count,
|
||||
'directors': directors, 'selected_director': ''}
|
||||
return render(request, 'movies.html', context)
|
||||
def bugs(request):
|
||||
context = {}
|
||||
return render(request, "bugs.html", context)
|
||||
|
||||
|
||||
def by_director(request, name):
|
||||
data = Movie.objects.to_dict(director=name)
|
||||
directors = Person.objects.directors()
|
||||
count = (len(data) - 1) * 4 + (len(data[-1]))
|
||||
context = {'movies': data, 'args': 'by_director', 'count': count,
|
||||
'directors': directors, 'selected_director': name}
|
||||
return render(request, 'movies.html', context)
|
||||
def movie(request, id):
|
||||
context = {"movie": Movie.objects.get_movie(id)}
|
||||
return render(request, "movie.html", context)
|
||||
|
||||
|
||||
def addcount(request, id):
|
||||
response = ''
|
||||
if id:
|
||||
try:
|
||||
movie = Movie.objects.get(id=id)
|
||||
count = movie.count
|
||||
movie.count = F('count') + 1
|
||||
movie.save()
|
||||
response = count + 1
|
||||
except Movie.DoesNotExist:
|
||||
pass
|
||||
|
||||
return HttpResponse(response)
|
||||
def movies(request, key):
|
||||
context = {"sections": {"Llave": "Valor"}}
|
||||
return render(request, "movies.html", context)
|
||||
|
|
|
@ -5,7 +5,7 @@ import sys
|
|||
|
||||
|
||||
def main():
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mauflix.settings')
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mauflix.settings")
|
||||
try:
|
||||
from django.core.management import execute_from_command_line
|
||||
except ImportError as exc:
|
||||
|
@ -17,5 +17,5 @@ def main():
|
|||
execute_from_command_line(sys.argv)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -2,4 +2,4 @@
|
|||
|
||||
|
||||
# ~ class SuitConfig(DjangoSuitConfig):
|
||||
# ~ layout = 'horizontal'
|
||||
# ~ layout = 'horizontal'
|
||||
|
|
|
@ -1,146 +0,0 @@
|
|||
"""
|
||||
Django settings for mauflix project.
|
||||
|
||||
Generated by 'django-admin startproject' using Django 2.2.4.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/2.2/topics/settings/
|
||||
|
||||
For the full list of settings and their values, see
|
||||
https://docs.djangoproject.com/en/2.2/ref/settings/
|
||||
"""
|
||||
|
||||
import os
|
||||
import re
|
||||
|
||||
from .conf import (
|
||||
DEBUG,
|
||||
DEFAULT_DB,
|
||||
SECRET_KEY,
|
||||
TOKEN_MASTODON,
|
||||
TOKEN_TELEGRAM,
|
||||
CHAT_ID,
|
||||
API_TOKEN,
|
||||
)
|
||||
|
||||
|
||||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
PATH_TEMPLATES = os.path.join(BASE_DIR, 'templates')
|
||||
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
|
||||
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
|
||||
MEDIA_URL = 'media/'
|
||||
|
||||
|
||||
ALLOWED_HOSTS = ['mauflix.elmau.net', 'elmau.net']
|
||||
if DEBUG:
|
||||
ALLOWED_HOSTS = ['*']
|
||||
|
||||
|
||||
# Application definition
|
||||
|
||||
INSTALLED_APPS = [
|
||||
'django_admin_listfilter_dropdown',
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'main.apps.MainConfig',
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
'django.middleware.security.SecurityMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
]
|
||||
|
||||
ROOT_URLCONF = 'mauflix.urls'
|
||||
|
||||
TEMPLATES = [
|
||||
{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': [PATH_TEMPLATES],
|
||||
'APP_DIRS': True,
|
||||
'OPTIONS': {
|
||||
'context_processors': [
|
||||
'django.template.context_processors.debug',
|
||||
'django.template.context_processors.request',
|
||||
'django.contrib.auth.context_processors.auth',
|
||||
'django.contrib.messages.context_processors.messages',
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
WSGI_APPLICATION = 'mauflix.wsgi.application'
|
||||
|
||||
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases
|
||||
|
||||
DATABASES = {'default': DEFAULT_DB}
|
||||
|
||||
|
||||
# Password validation
|
||||
# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators
|
||||
|
||||
AUTH_PASSWORD_VALIDATORS = [
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
# Internationalization
|
||||
# https://docs.djangoproject.com/en/2.2/topics/i18n/
|
||||
|
||||
LANGUAGE_CODE = 'es-MX'
|
||||
|
||||
TIME_ZONE = 'America/Mexico_City'
|
||||
|
||||
USE_I18N = True
|
||||
|
||||
USE_L10N = True
|
||||
|
||||
USE_TZ = False
|
||||
|
||||
|
||||
# Static files (CSS, JavaScript, Images)
|
||||
# https://docs.djangoproject.com/en/2.2/howto/static-files/
|
||||
|
||||
STATIC_URL = '/static/'
|
||||
# ~ STATICFILES_DIRS = [STATIC_ROOT]
|
||||
|
||||
DISALLOWED_USER_AGENTS = (
|
||||
re.compile(r'.*Googlebot', re.IGNORECASE),
|
||||
re.compile(r'.*Spider', re.IGNORECASE),
|
||||
re.compile(r'.*bingbot', re.IGNORECASE),
|
||||
re.compile(r'.*MJ12bot', re.IGNORECASE),
|
||||
re.compile(r'.*Slurp', re.IGNORECASE),
|
||||
re.compile(r'.*python-requests', re.IGNORECASE),
|
||||
re.compile(r'.*Netcraft', re.IGNORECASE),
|
||||
re.compile(r'.*AhrefsBot', re.IGNORECASE),
|
||||
)
|
||||
|
||||
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
|
||||
SESSION_COOKIE_AGE = 3600
|
||||
|
||||
|
||||
# ~ URL_CDN = 'https://sos-ch-dk-2.exo.io/mauflix/{}/{}'
|
||||
URL_CDN = 'https://mauflix.elmau.net/{}'
|
||||
URL_MASTODON = 'https://mstdn.mx/'
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
from django.contrib import admin
|
||||
from django.urls import path
|
||||
from django.conf import settings
|
||||
|
@ -12,18 +11,18 @@ from main.feeds import LatestMoviesFeed
|
|||
from main.api import ResourceMovies
|
||||
|
||||
|
||||
v1_api = Api(api_name='v1')
|
||||
v1_api = Api(api_name="v1")
|
||||
v1_api.register(ResourceMovies())
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
path('', views.home, name='home'),
|
||||
path('movies/', views.movies, name='movies'),
|
||||
path('movies/<str:args>', views.movies, name='movies'),
|
||||
path('movies/director/<str:name>', views.by_director, name='by_director'),
|
||||
path('addcount/<int:id>/', views.addcount, name='addcount'),
|
||||
path('ultimas/rss/', LatestMoviesFeed()),
|
||||
path('admin/', admin.site.urls),
|
||||
path('api/', include(v1_api.urls)),
|
||||
path("", views.home, name="home"),
|
||||
path("search/", views.search, name="search"),
|
||||
path("about/", views.about, name="about"),
|
||||
path("bugs/", views.bugs, name="bugs"),
|
||||
path("movies/<str:key>", 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)),
|
||||
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||
|
||||
|
|
|
@ -11,6 +11,6 @@ import os
|
|||
|
||||
from django.core.wsgi import get_wsgi_application
|
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mauflix.settings')
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mauflix.settings")
|
||||
|
||||
application = get_wsgi_application()
|
||||
|
|
|
@ -14,7 +14,7 @@ select.admin-autocomplete {
|
|||
|
||||
.select2-container--admin-autocomplete.select2-container--focus .select2-selection,
|
||||
.select2-container--admin-autocomplete.select2-container--open .select2-selection {
|
||||
border-color: #999;
|
||||
border-color: var(--body-quiet-color);
|
||||
min-height: 30px;
|
||||
}
|
||||
|
||||
|
@ -29,13 +29,13 @@ select.admin-autocomplete {
|
|||
}
|
||||
|
||||
.select2-container--admin-autocomplete .select2-selection--single {
|
||||
background-color: #fff;
|
||||
border: 1px solid #ccc;
|
||||
background-color: var(--body-bg);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.select2-container--admin-autocomplete .select2-selection--single .select2-selection__rendered {
|
||||
color: #444;
|
||||
color: var(--body-fg);
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ select.admin-autocomplete {
|
|||
}
|
||||
|
||||
.select2-container--admin-autocomplete .select2-selection--single .select2-selection__placeholder {
|
||||
color: #999;
|
||||
color: var(--body-quiet-color);
|
||||
}
|
||||
|
||||
.select2-container--admin-autocomplete .select2-selection--single .select2-selection__arrow {
|
||||
|
@ -80,7 +80,7 @@ select.admin-autocomplete {
|
|||
}
|
||||
|
||||
.select2-container--admin-autocomplete.select2-container--disabled .select2-selection--single {
|
||||
background-color: #eee;
|
||||
background-color: var(--darkened-bg);
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
|
@ -94,8 +94,8 @@ select.admin-autocomplete {
|
|||
}
|
||||
|
||||
.select2-container--admin-autocomplete .select2-selection--multiple {
|
||||
background-color: white;
|
||||
border: 1px solid #ccc;
|
||||
background-color: var(--body-bg);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 4px;
|
||||
cursor: text;
|
||||
}
|
||||
|
@ -104,8 +104,10 @@ select.admin-autocomplete {
|
|||
box-sizing: border-box;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0 5px;
|
||||
padding: 0 10px 5px 5px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__rendered li {
|
||||
|
@ -113,7 +115,7 @@ select.admin-autocomplete {
|
|||
}
|
||||
|
||||
.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__placeholder {
|
||||
color: #999;
|
||||
color: var(--body-quiet-color);
|
||||
margin-top: 5px;
|
||||
float: left;
|
||||
}
|
||||
|
@ -123,11 +125,13 @@ select.admin-autocomplete {
|
|||
float: right;
|
||||
font-weight: bold;
|
||||
margin: 5px;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__choice {
|
||||
background-color: #e4e4e4;
|
||||
border: 1px solid #ccc;
|
||||
background-color: var(--darkened-bg);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 4px;
|
||||
cursor: default;
|
||||
float: left;
|
||||
|
@ -137,7 +141,7 @@ select.admin-autocomplete {
|
|||
}
|
||||
|
||||
.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__choice__remove {
|
||||
color: #999;
|
||||
color: var(--body-quiet-color);
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
font-weight: bold;
|
||||
|
@ -145,7 +149,7 @@ select.admin-autocomplete {
|
|||
}
|
||||
|
||||
.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__choice__remove:hover {
|
||||
color: #333;
|
||||
color: var(--body-fg);
|
||||
}
|
||||
|
||||
.select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder, .select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-search--inline {
|
||||
|
@ -163,12 +167,12 @@ select.admin-autocomplete {
|
|||
}
|
||||
|
||||
.select2-container--admin-autocomplete.select2-container--focus .select2-selection--multiple {
|
||||
border: solid #999 1px;
|
||||
border: solid var(--body-quiet-color) 1px;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.select2-container--admin-autocomplete.select2-container--disabled .select2-selection--multiple {
|
||||
background-color: #eee;
|
||||
background-color: var(--darkened-bg);
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
|
@ -186,12 +190,20 @@ select.admin-autocomplete {
|
|||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
.select2-container--admin-autocomplete .select2-search--dropdown {
|
||||
background: var(--darkened-bg);
|
||||
}
|
||||
|
||||
.select2-container--admin-autocomplete .select2-search--dropdown .select2-search__field {
|
||||
border: 1px solid #ccc;
|
||||
background: var(--body-bg);
|
||||
color: var(--body-fg);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.select2-container--admin-autocomplete .select2-search--inline .select2-search__field {
|
||||
background: transparent;
|
||||
color: var(--body-fg);
|
||||
border: none;
|
||||
outline: 0;
|
||||
box-shadow: none;
|
||||
|
@ -201,6 +213,8 @@ select.admin-autocomplete {
|
|||
.select2-container--admin-autocomplete .select2-results > .select2-results__options {
|
||||
max-height: 200px;
|
||||
overflow-y: auto;
|
||||
color: var(--body-fg);
|
||||
background: var(--body-bg);
|
||||
}
|
||||
|
||||
.select2-container--admin-autocomplete .select2-results__option[role=group] {
|
||||
|
@ -208,11 +222,12 @@ select.admin-autocomplete {
|
|||
}
|
||||
|
||||
.select2-container--admin-autocomplete .select2-results__option[aria-disabled=true] {
|
||||
color: #999;
|
||||
color: var(--body-quiet-color);
|
||||
}
|
||||
|
||||
.select2-container--admin-autocomplete .select2-results__option[aria-selected=true] {
|
||||
background-color: #ddd;
|
||||
background-color: var(--selected-bg);
|
||||
color: var(--body-fg);
|
||||
}
|
||||
|
||||
.select2-container--admin-autocomplete .select2-results__option .select2-results__option {
|
||||
|
@ -249,8 +264,8 @@ select.admin-autocomplete {
|
|||
}
|
||||
|
||||
.select2-container--admin-autocomplete .select2-results__option--highlighted[aria-selected] {
|
||||
background-color: #79aec8;
|
||||
color: white;
|
||||
background-color: var(--primary);
|
||||
color: var(--primary-fg);
|
||||
}
|
||||
|
||||
.select2-container--admin-autocomplete .select2-results__group {
|
||||
|
|
|
@ -4,6 +4,93 @@
|
|||
|
||||
@import url(fonts.css);
|
||||
|
||||
/* VARIABLE DEFINITIONS */
|
||||
:root {
|
||||
--primary: #79aec8;
|
||||
--secondary: #417690;
|
||||
--accent: #f5dd5d;
|
||||
--primary-fg: #fff;
|
||||
|
||||
--body-fg: #333;
|
||||
--body-bg: #fff;
|
||||
--body-quiet-color: #666;
|
||||
--body-loud-color: #000;
|
||||
|
||||
--header-color: #ffc;
|
||||
--header-branding-color: var(--accent);
|
||||
--header-bg: var(--secondary);
|
||||
--header-link-color: var(--primary-fg);
|
||||
|
||||
--breadcrumbs-fg: #c4dce8;
|
||||
--breadcrumbs-link-fg: var(--body-bg);
|
||||
--breadcrumbs-bg: var(--primary);
|
||||
|
||||
--link-fg: #447e9b;
|
||||
--link-hover-color: #036;
|
||||
--link-selected-fg: #5b80b2;
|
||||
|
||||
--hairline-color: #e8e8e8;
|
||||
--border-color: #ccc;
|
||||
|
||||
--error-fg: #ba2121;
|
||||
|
||||
--message-success-bg: #dfd;
|
||||
--message-warning-bg: #ffc;
|
||||
--message-error-bg: #ffefef;
|
||||
|
||||
--darkened-bg: #f8f8f8; /* A bit darker than --body-bg */
|
||||
--selected-bg: #e4e4e4; /* E.g. selected table cells */
|
||||
--selected-row: #ffc;
|
||||
|
||||
--button-fg: #fff;
|
||||
--button-bg: var(--primary);
|
||||
--button-hover-bg: #609ab6;
|
||||
--default-button-bg: var(--secondary);
|
||||
--default-button-hover-bg: #205067;
|
||||
--close-button-bg: #888; /* Previously #bbb, contrast 1.92 */
|
||||
--close-button-hover-bg: #747474;
|
||||
--delete-button-bg: #ba2121;
|
||||
--delete-button-hover-bg: #a41515;
|
||||
|
||||
--object-tools-fg: var(--button-fg);
|
||||
--object-tools-bg: var(--close-button-bg);
|
||||
--object-tools-hover-bg: var(--close-button-hover-bg);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--primary: #264b5d;
|
||||
--primary-fg: #eee;
|
||||
|
||||
--body-fg: #eeeeee;
|
||||
--body-bg: #121212;
|
||||
--body-quiet-color: #e0e0e0;
|
||||
--body-loud-color: #ffffff;
|
||||
|
||||
--breadcrumbs-link-fg: #e0e0e0;
|
||||
--breadcrumbs-bg: var(--primary);
|
||||
|
||||
--link-fg: #81d4fa;
|
||||
--link-hover-color: #4ac1f7;
|
||||
--link-selected-fg: #6f94c6;
|
||||
|
||||
--hairline-color: #272727;
|
||||
--border-color: #353535;
|
||||
|
||||
--error-fg: #e35f5f;
|
||||
--message-success-bg: #006b1b;
|
||||
--message-warning-bg: #583305;
|
||||
--message-error-bg: #570808;
|
||||
|
||||
--darkened-bg: #212121;
|
||||
--selected-bg: #1b1b1b;
|
||||
--selected-row: #00363a;
|
||||
|
||||
--close-button-bg: #333333;
|
||||
--close-button-hover-bg: #666666;
|
||||
}
|
||||
}
|
||||
|
||||
html, body {
|
||||
height: 100%;
|
||||
}
|
||||
|
@ -13,19 +100,20 @@ body {
|
|||
padding: 0;
|
||||
font-size: 14px;
|
||||
font-family: "Roboto","Lucida Grande","DejaVu Sans","Bitstream Vera Sans",Verdana,Arial,sans-serif;
|
||||
color: #333;
|
||||
background: #fff;
|
||||
color: var(--body-fg);
|
||||
background: var(--body-bg);
|
||||
}
|
||||
|
||||
/* LINKS */
|
||||
|
||||
a:link, a:visited {
|
||||
color: #447e9b;
|
||||
color: var(--link-fg);
|
||||
text-decoration: none;
|
||||
transition: color 0.15s, background 0.15s;
|
||||
}
|
||||
|
||||
a:focus, a:hover {
|
||||
color: #036;
|
||||
color: var(--link-hover-color);
|
||||
}
|
||||
|
||||
a:focus {
|
||||
|
@ -37,7 +125,7 @@ a img {
|
|||
}
|
||||
|
||||
a.section:link, a.section:visited {
|
||||
color: #fff;
|
||||
color: var(--header-link-color);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
|
@ -64,7 +152,7 @@ h1 {
|
|||
margin: 0 0 20px;
|
||||
font-weight: 300;
|
||||
font-size: 20px;
|
||||
color: #666;
|
||||
color: var(--body-quiet-color);
|
||||
}
|
||||
|
||||
h2 {
|
||||
|
@ -80,7 +168,7 @@ h2.subhead {
|
|||
h3 {
|
||||
font-size: 14px;
|
||||
margin: .8em 0 .3em 0;
|
||||
color: #666;
|
||||
color: var(--body-quiet-color);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
@ -93,7 +181,7 @@ h4 {
|
|||
h5 {
|
||||
font-size: 10px;
|
||||
margin: 1.5em 0 .5em 0;
|
||||
color: #666;
|
||||
color: var(--body-quiet-color);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
@ -131,7 +219,7 @@ fieldset {
|
|||
min-width: 0;
|
||||
padding: 0;
|
||||
border: none;
|
||||
border-top: 1px solid #eee;
|
||||
border-top: 1px solid var(--hairline-color);
|
||||
}
|
||||
|
||||
blockquote {
|
||||
|
@ -144,14 +232,14 @@ blockquote {
|
|||
|
||||
code, pre {
|
||||
font-family: "Bitstream Vera Sans Mono", Monaco, "Courier New", Courier, monospace;
|
||||
color: #666;
|
||||
color: var(--body-quiet-color);
|
||||
font-size: 12px;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
pre.literal-block {
|
||||
margin: 10px;
|
||||
background: #eee;
|
||||
background: var(--darkened-bg);
|
||||
padding: 6px 8px;
|
||||
}
|
||||
|
||||
|
@ -161,8 +249,8 @@ code strong {
|
|||
|
||||
hr {
|
||||
clear: both;
|
||||
color: #eee;
|
||||
background-color: #eee;
|
||||
color: var(--hairline-color);
|
||||
background-color: var(--hairline-color);
|
||||
height: 1px;
|
||||
border: none;
|
||||
margin: 0;
|
||||
|
@ -183,7 +271,7 @@ hr {
|
|||
|
||||
.help, p.help, form p.help, div.help, form div.help, div.help li {
|
||||
font-size: 11px;
|
||||
color: #999;
|
||||
color: var(--body-quiet-color);
|
||||
}
|
||||
|
||||
div.help ul {
|
||||
|
@ -199,7 +287,7 @@ p img, h1 img, h2 img, h3 img, h4 img, td img {
|
|||
}
|
||||
|
||||
.quiet, a.quiet:link, a.quiet:visited {
|
||||
color: #999;
|
||||
color: var(--body-quiet-color);
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
|
@ -211,20 +299,23 @@ p img, h1 img, h2 img, h3 img, h4 img, td img {
|
|||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* TABLES */
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-color: #ccc;
|
||||
border-color: var(--border-color);
|
||||
}
|
||||
|
||||
td, th {
|
||||
font-size: 13px;
|
||||
line-height: 16px;
|
||||
border-bottom: 1px solid #eee;
|
||||
border-bottom: 1px solid var(--hairline-color);
|
||||
vertical-align: top;
|
||||
padding: 8px;
|
||||
font-family: "Roboto", "Lucida Grande", Verdana, Arial, sans-serif;
|
||||
}
|
||||
|
||||
th {
|
||||
|
@ -234,37 +325,37 @@ th {
|
|||
|
||||
thead th,
|
||||
tfoot td {
|
||||
color: #666;
|
||||
color: var(--body-quiet-color);
|
||||
padding: 5px 10px;
|
||||
font-size: 11px;
|
||||
background: #fff;
|
||||
background: var(--body-bg);
|
||||
border: none;
|
||||
border-top: 1px solid #eee;
|
||||
border-bottom: 1px solid #eee;
|
||||
border-top: 1px solid var(--hairline-color);
|
||||
border-bottom: 1px solid var(--hairline-color);
|
||||
}
|
||||
|
||||
tfoot td {
|
||||
border-bottom: none;
|
||||
border-top: 1px solid #eee;
|
||||
border-top: 1px solid var(--hairline-color);
|
||||
}
|
||||
|
||||
thead th.required {
|
||||
color: #000;
|
||||
color: var(--body-loud-color);
|
||||
}
|
||||
|
||||
tr.alt {
|
||||
background: #f6f6f6;
|
||||
background: var(--darkened-bg);
|
||||
}
|
||||
|
||||
tr:nth-child(odd), .row-form-errors {
|
||||
background: #fff;
|
||||
background: var(--body-bg);
|
||||
}
|
||||
|
||||
tr:nth-child(even),
|
||||
tr:nth-child(even) .errorlist,
|
||||
tr:nth-child(odd) + .row-form-errors,
|
||||
tr:nth-child(odd) + .row-form-errors .errorlist {
|
||||
background: #f9f9f9;
|
||||
background: var(--darkened-bg);
|
||||
}
|
||||
|
||||
/* SORTABLE TABLES */
|
||||
|
@ -273,15 +364,15 @@ thead th {
|
|||
padding: 5px 10px;
|
||||
line-height: normal;
|
||||
text-transform: uppercase;
|
||||
background: #f6f6f6;
|
||||
background: var(--darkened-bg);
|
||||
}
|
||||
|
||||
thead th a:link, thead th a:visited {
|
||||
color: #666;
|
||||
color: var(--body-quiet-color);
|
||||
}
|
||||
|
||||
thead th.sorted {
|
||||
background: #eee;
|
||||
background: var(--selected-bg);
|
||||
}
|
||||
|
||||
thead th.sorted .text {
|
||||
|
@ -300,7 +391,7 @@ table thead th .text a {
|
|||
}
|
||||
|
||||
table thead th .text a:focus, table thead th .text a:hover {
|
||||
background: #eee;
|
||||
background: var(--selected-bg);
|
||||
}
|
||||
|
||||
thead th.sorted a.sortremove {
|
||||
|
@ -347,12 +438,12 @@ table thead th.sorted .sortoptions a.sortremove:after {
|
|||
left: 3px;
|
||||
font-weight: 200;
|
||||
font-size: 18px;
|
||||
color: #999;
|
||||
color: var(--body-quiet-color);
|
||||
}
|
||||
|
||||
table thead th.sorted .sortoptions a.sortremove:focus:after,
|
||||
table thead th.sorted .sortoptions a.sortremove:hover:after {
|
||||
color: #447e9b;
|
||||
color: var(--link-fg);
|
||||
}
|
||||
|
||||
table thead th.sorted .sortoptions a.sortremove:focus,
|
||||
|
@ -399,16 +490,18 @@ textarea {
|
|||
|
||||
input[type=text], input[type=password], input[type=email], input[type=url],
|
||||
input[type=number], input[type=tel], textarea, select, .vTextField {
|
||||
border: 1px solid #ccc;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 4px;
|
||||
padding: 5px 6px;
|
||||
margin-top: 0;
|
||||
color: var(--body-fg);
|
||||
background-color: var(--body-bg);
|
||||
}
|
||||
|
||||
input[type=text]:focus, input[type=password]:focus, input[type=email]:focus,
|
||||
input[type=url]:focus, input[type=number]:focus, input[type=tel]:focus,
|
||||
textarea:focus, select:focus, .vTextField:focus {
|
||||
border-color: #999;
|
||||
border-color: var(--body-quiet-color);
|
||||
}
|
||||
|
||||
select {
|
||||
|
@ -424,12 +517,13 @@ select[multiple] {
|
|||
/* FORM BUTTONS */
|
||||
|
||||
.button, input[type=submit], input[type=button], .submit-row input, a.button {
|
||||
background: #79aec8;
|
||||
background: var(--button-bg);
|
||||
padding: 10px 15px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
color: #fff;
|
||||
color: var(--button-fg);
|
||||
cursor: pointer;
|
||||
transition: background 0.15s;
|
||||
}
|
||||
|
||||
a.button {
|
||||
|
@ -439,7 +533,7 @@ a.button {
|
|||
.button:active, input[type=submit]:active, input[type=button]:active,
|
||||
.button:focus, input[type=submit]:focus, input[type=button]:focus,
|
||||
.button:hover, input[type=submit]:hover, input[type=button]:hover {
|
||||
background: #609ab6;
|
||||
background: var(--button-hover-bg);
|
||||
}
|
||||
|
||||
.button[disabled], input[type=submit][disabled], input[type=button][disabled] {
|
||||
|
@ -450,13 +544,13 @@ a.button {
|
|||
float: right;
|
||||
border: none;
|
||||
font-weight: 400;
|
||||
background: #417690;
|
||||
background: var(--default-button-bg);
|
||||
}
|
||||
|
||||
.button.default:active, input[type=submit].default:active,
|
||||
.button.default:focus, input[type=submit].default:focus,
|
||||
.button.default:hover, input[type=submit].default:hover {
|
||||
background: #205067;
|
||||
background: var(--default-button-hover-bg);
|
||||
}
|
||||
|
||||
.button[disabled].default,
|
||||
|
@ -471,7 +565,7 @@ input[type=button][disabled].default {
|
|||
.module {
|
||||
border: none;
|
||||
margin-bottom: 30px;
|
||||
background: #fff;
|
||||
background: var(--body-bg);
|
||||
}
|
||||
|
||||
.module p, .module ul, .module h3, .module h4, .module dl, .module pre {
|
||||
|
@ -497,8 +591,8 @@ input[type=button][disabled].default {
|
|||
font-weight: 400;
|
||||
font-size: 13px;
|
||||
text-align: left;
|
||||
background: #79aec8;
|
||||
color: #fff;
|
||||
background: var(--primary);
|
||||
color: var(--header-link-color);
|
||||
}
|
||||
|
||||
.module caption,
|
||||
|
@ -525,18 +619,18 @@ ul.messagelist li {
|
|||
font-size: 13px;
|
||||
padding: 10px 10px 10px 65px;
|
||||
margin: 0 0 10px 0;
|
||||
background: #dfd url(../img/icon-yes.svg) 40px 12px no-repeat;
|
||||
background: var(--message-success-bg) url(../img/icon-yes.svg) 40px 12px no-repeat;
|
||||
background-size: 16px auto;
|
||||
color: #333;
|
||||
color: var(--body-fg);
|
||||
}
|
||||
|
||||
ul.messagelist li.warning {
|
||||
background: #ffc url(../img/icon-alert.svg) 40px 14px no-repeat;
|
||||
background: var(--message-warning-bg) url(../img/icon-alert.svg) 40px 14px no-repeat;
|
||||
background-size: 14px auto;
|
||||
}
|
||||
|
||||
ul.messagelist li.error {
|
||||
background: #ffefef url(../img/icon-no.svg) 40px 12px no-repeat;
|
||||
background: var(--message-error-bg) url(../img/icon-no.svg) 40px 12px no-repeat;
|
||||
background-size: 16px auto;
|
||||
}
|
||||
|
||||
|
@ -546,24 +640,26 @@ ul.messagelist li.error {
|
|||
display: block;
|
||||
padding: 10px 12px;
|
||||
margin: 0 0 10px 0;
|
||||
color: #ba2121;
|
||||
border: 1px solid #ba2121;
|
||||
color: var(--error-fg);
|
||||
border: 1px solid var(--error-fg);
|
||||
border-radius: 4px;
|
||||
background-color: #fff;
|
||||
background-color: var(--body-bg);
|
||||
background-position: 5px 12px;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
ul.errorlist {
|
||||
margin: 0 0 4px;
|
||||
padding: 0;
|
||||
color: #ba2121;
|
||||
background: #fff;
|
||||
color: var(--error-fg);
|
||||
background: var(--body-bg);
|
||||
}
|
||||
|
||||
ul.errorlist li {
|
||||
font-size: 13px;
|
||||
display: block;
|
||||
margin-bottom: 4px;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
ul.errorlist li:first-child {
|
||||
|
@ -587,7 +683,7 @@ td ul.errorlist li {
|
|||
.form-row.errors {
|
||||
margin: 0;
|
||||
border: none;
|
||||
border-bottom: 1px solid #eee;
|
||||
border-bottom: 1px solid var(--hairline-color);
|
||||
background: none;
|
||||
}
|
||||
|
||||
|
@ -597,7 +693,7 @@ td ul.errorlist li {
|
|||
|
||||
.errors input, .errors select, .errors textarea,
|
||||
td ul.errorlist + input, td ul.errorlist + select, td ul.errorlist + textarea {
|
||||
border: 1px solid #ba2121;
|
||||
border: 1px solid var(--error-fg);
|
||||
}
|
||||
|
||||
.description {
|
||||
|
@ -608,20 +704,19 @@ td ul.errorlist + input, td ul.errorlist + select, td ul.errorlist + textarea {
|
|||
/* BREADCRUMBS */
|
||||
|
||||
div.breadcrumbs {
|
||||
background: #79aec8;
|
||||
background: var(--breadcrumbs-bg);
|
||||
padding: 10px 40px;
|
||||
border: none;
|
||||
font-size: 14px;
|
||||
color: #c4dce8;
|
||||
color: var(--breadcrumbs-fg);
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
div.breadcrumbs a {
|
||||
color: #fff;
|
||||
color: var(--breadcrumbs-link-fg);
|
||||
}
|
||||
|
||||
div.breadcrumbs a:focus, div.breadcrumbs a:hover {
|
||||
color: #c4dce8;
|
||||
color: var(--breadcrumbs-fg);
|
||||
}
|
||||
|
||||
/* ACTION ICONS */
|
||||
|
@ -647,11 +742,11 @@ div.breadcrumbs a:focus, div.breadcrumbs a:hover {
|
|||
}
|
||||
|
||||
a.deletelink:link, a.deletelink:visited {
|
||||
color: #CC3434;
|
||||
color: #CC3434; /* XXX Probably unused? */
|
||||
}
|
||||
|
||||
a.deletelink:focus, a.deletelink:hover {
|
||||
color: #993333;
|
||||
color: #993333; /* XXX Probably unused? */
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
|
@ -666,14 +761,6 @@ a.deletelink:focus, a.deletelink:hover {
|
|||
margin-top: -48px;
|
||||
}
|
||||
|
||||
.form-row .object-tools {
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
float: none;
|
||||
height: 2em;
|
||||
padding-left: 3.5em;
|
||||
}
|
||||
|
||||
.object-tools li {
|
||||
display: block;
|
||||
float: left;
|
||||
|
@ -689,29 +776,29 @@ a.deletelink:focus, a.deletelink:hover {
|
|||
display: block;
|
||||
float: left;
|
||||
padding: 3px 12px;
|
||||
background: #999;
|
||||
background: var(--object-tools-bg);
|
||||
color: var(--object-tools-fg);
|
||||
font-weight: 400;
|
||||
font-size: 11px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.object-tools a:focus, .object-tools a:hover {
|
||||
background-color: #417690;
|
||||
background-color: var(--object-tools-hover-bg);
|
||||
}
|
||||
|
||||
.object-tools a:focus{
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.object-tools a.viewsitelink, .object-tools a.golink,.object-tools a.addlink {
|
||||
.object-tools a.viewsitelink, .object-tools a.addlink {
|
||||
background-repeat: no-repeat;
|
||||
background-position: right 7px center;
|
||||
padding-right: 26px;
|
||||
}
|
||||
|
||||
.object-tools a.viewsitelink, .object-tools a.golink {
|
||||
.object-tools a.viewsitelink {
|
||||
background-image: url(../img/tooltag-arrowright.svg);
|
||||
}
|
||||
|
||||
|
@ -813,13 +900,13 @@ table#change-history tbody th {
|
|||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 10px 40px;
|
||||
background: #417690;
|
||||
color: #ffc;
|
||||
background: var(--header-bg);
|
||||
color: var(--header-color);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#header a:link, #header a:visited {
|
||||
color: #fff;
|
||||
color: var(--header-link-color);
|
||||
}
|
||||
|
||||
#header a:focus , #header a:hover {
|
||||
|
@ -835,11 +922,11 @@ table#change-history tbody th {
|
|||
margin: 0 20px 0 0;
|
||||
font-weight: 300;
|
||||
font-size: 24px;
|
||||
color: #f5dd5d;
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
#branding h1, #branding h1 a:link, #branding h1 a:visited {
|
||||
color: #f5dd5d;
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
#branding h2 {
|
||||
|
@ -847,7 +934,7 @@ table#change-history tbody th {
|
|||
font-size: 14px;
|
||||
margin: -8px 0 8px 0;
|
||||
font-weight: normal;
|
||||
color: #ffc;
|
||||
color: var(--header-color);
|
||||
}
|
||||
|
||||
#branding a:hover {
|
||||
|
@ -871,14 +958,14 @@ table#change-history tbody th {
|
|||
|
||||
#user-tools a:focus, #user-tools a:hover {
|
||||
text-decoration: none;
|
||||
border-bottom-color: #79aec8;
|
||||
color: #79aec8;
|
||||
border-bottom-color: var(--primary);
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
/* SIDEBAR */
|
||||
|
||||
#content-related {
|
||||
background: #f8f8f8;
|
||||
background: var(--darkened-bg);
|
||||
}
|
||||
|
||||
#content-related .module {
|
||||
|
@ -886,8 +973,7 @@ table#change-history tbody th {
|
|||
}
|
||||
|
||||
#content-related h3 {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
color: var(--body-quiet-color);
|
||||
padding: 0 16px;
|
||||
margin: 0 0 16px;
|
||||
}
|
||||
|
@ -916,22 +1002,22 @@ table#change-history tbody th {
|
|||
background: none;
|
||||
padding: 16px;
|
||||
margin-bottom: 16px;
|
||||
border-bottom: 1px solid #eaeaea;
|
||||
border-bottom: 1px solid var(--hairline-color);
|
||||
font-size: 18px;
|
||||
color: #333;
|
||||
color: var(--body-fg);
|
||||
}
|
||||
|
||||
.delete-confirmation form input[type="submit"] {
|
||||
background: #ba2121;
|
||||
background: var(--delete-button-bg);
|
||||
border-radius: 4px;
|
||||
padding: 10px 15px;
|
||||
color: #fff;
|
||||
color: var(--button-fg);
|
||||
}
|
||||
|
||||
.delete-confirmation form input[type="submit"]:active,
|
||||
.delete-confirmation form input[type="submit"]:focus,
|
||||
.delete-confirmation form input[type="submit"]:hover {
|
||||
background: #a41515;
|
||||
background: var(--delete-button-hover-bg);
|
||||
}
|
||||
|
||||
.delete-confirmation form .cancel-link {
|
||||
|
@ -939,17 +1025,17 @@ table#change-history tbody th {
|
|||
vertical-align: middle;
|
||||
height: 15px;
|
||||
line-height: 15px;
|
||||
background: #ddd;
|
||||
border-radius: 4px;
|
||||
padding: 10px 15px;
|
||||
color: #333;
|
||||
color: var(--button-fg);
|
||||
background: var(--close-button-bg);
|
||||
margin: 0 0 0 10px;
|
||||
}
|
||||
|
||||
.delete-confirmation form .cancel-link:active,
|
||||
.delete-confirmation form .cancel-link:focus,
|
||||
.delete-confirmation form .cancel-link:hover {
|
||||
background: #ccc;
|
||||
background: var(--close-button-hover-bg);
|
||||
}
|
||||
|
||||
/* POPUP */
|
||||
|
|
|
@ -40,13 +40,13 @@
|
|||
}
|
||||
|
||||
#changelist .toplinks {
|
||||
border-bottom: 1px solid #ddd;
|
||||
border-bottom: 1px solid var(--hairline-color);
|
||||
}
|
||||
|
||||
#changelist .paginator {
|
||||
color: #666;
|
||||
border-bottom: 1px solid #eee;
|
||||
background: #fff;
|
||||
color: var(--body-quiet-color);
|
||||
border-bottom: 1px solid var(--hairline-color);
|
||||
background: var(--body-bg);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
@ -68,7 +68,7 @@
|
|||
}
|
||||
|
||||
#changelist table tfoot {
|
||||
color: #666;
|
||||
color: var(--body-quiet-color);
|
||||
}
|
||||
|
||||
/* TOOLBAR */
|
||||
|
@ -76,22 +76,22 @@
|
|||
#toolbar {
|
||||
padding: 8px 10px;
|
||||
margin-bottom: 15px;
|
||||
border-top: 1px solid #eee;
|
||||
border-bottom: 1px solid #eee;
|
||||
background: #f8f8f8;
|
||||
color: #666;
|
||||
border-top: 1px solid var(--hairline-color);
|
||||
border-bottom: 1px solid var(--hairline-color);
|
||||
background: var(--darkened-bg);
|
||||
color: var(--body-quiet-color);
|
||||
}
|
||||
|
||||
#toolbar form input {
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
padding: 5px;
|
||||
color: #333;
|
||||
color: var(--body-fg);
|
||||
}
|
||||
|
||||
#toolbar #searchbar {
|
||||
height: 19px;
|
||||
border: 1px solid #ccc;
|
||||
border: 1px solid var(--border-color);
|
||||
padding: 2px 5px;
|
||||
margin: 0;
|
||||
vertical-align: top;
|
||||
|
@ -100,24 +100,24 @@
|
|||
}
|
||||
|
||||
#toolbar #searchbar:focus {
|
||||
border-color: #999;
|
||||
border-color: var(--body-quiet-color);
|
||||
}
|
||||
|
||||
#toolbar form input[type="submit"] {
|
||||
border: 1px solid #ccc;
|
||||
border: 1px solid var(--border-color);
|
||||
font-size: 13px;
|
||||
padding: 4px 8px;
|
||||
margin: 0;
|
||||
vertical-align: middle;
|
||||
background: #fff;
|
||||
background: var(--body-bg);
|
||||
box-shadow: 0 -15px 20px -10px rgba(0, 0, 0, 0.15) inset;
|
||||
cursor: pointer;
|
||||
color: #333;
|
||||
color: var(--body-fg);
|
||||
}
|
||||
|
||||
#toolbar form input[type="submit"]:focus,
|
||||
#toolbar form input[type="submit"]:hover {
|
||||
border-color: #999;
|
||||
border-color: var(--body-quiet-color);
|
||||
}
|
||||
|
||||
#changelist-search img {
|
||||
|
@ -128,9 +128,9 @@
|
|||
/* FILTER COLUMN */
|
||||
|
||||
#changelist-filter {
|
||||
flex: 0 0 240px;
|
||||
order: 1;
|
||||
width: 240px;
|
||||
background: #f8f8f8;
|
||||
background: var(--darkened-bg);
|
||||
border-left: none;
|
||||
margin: 0 0 0 30px;
|
||||
}
|
||||
|
@ -146,7 +146,6 @@
|
|||
|
||||
#changelist-filter h3 {
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
padding: 0 15px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
@ -154,7 +153,7 @@
|
|||
#changelist-filter ul {
|
||||
margin: 5px 0;
|
||||
padding: 0 15px 15px;
|
||||
border-bottom: 1px solid #eaeaea;
|
||||
border-bottom: 1px solid var(--hairline-color);
|
||||
}
|
||||
|
||||
#changelist-filter ul:last-child {
|
||||
|
@ -169,31 +168,31 @@
|
|||
|
||||
#changelist-filter a {
|
||||
display: block;
|
||||
color: #999;
|
||||
color: var(--body-quiet-color);
|
||||
text-overflow: ellipsis;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
#changelist-filter li.selected {
|
||||
border-left: 5px solid #eaeaea;
|
||||
border-left: 5px solid var(--hairline-color);
|
||||
padding-left: 10px;
|
||||
margin-left: -15px;
|
||||
}
|
||||
|
||||
#changelist-filter li.selected a {
|
||||
color: #5b80b2;
|
||||
color: var(--link-selected-fg);
|
||||
}
|
||||
|
||||
#changelist-filter a:focus, #changelist-filter a:hover,
|
||||
#changelist-filter li.selected a:focus,
|
||||
#changelist-filter li.selected a:hover {
|
||||
color: #036;
|
||||
color: var(--link-hover-color);
|
||||
}
|
||||
|
||||
#changelist-filter #changelist-filter-clear a {
|
||||
font-size: 13px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #eaeaea;
|
||||
border-bottom: 1px solid var(--hairline-color);
|
||||
}
|
||||
|
||||
/* DATE DRILLDOWN */
|
||||
|
@ -214,12 +213,12 @@
|
|||
}
|
||||
|
||||
.change-list ul.toplinks .date-back a {
|
||||
color: #999;
|
||||
color: var(--body-quiet-color);
|
||||
}
|
||||
|
||||
.change-list ul.toplinks .date-back a:focus,
|
||||
.change-list ul.toplinks .date-back a:hover {
|
||||
color: #036;
|
||||
color: var(--link-hover-color);
|
||||
}
|
||||
|
||||
/* PAGINATOR */
|
||||
|
@ -230,26 +229,26 @@
|
|||
padding-bottom: 10px;
|
||||
line-height: 22px;
|
||||
margin: 0;
|
||||
border-top: 1px solid #ddd;
|
||||
border-top: 1px solid var(--hairline-color);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.paginator a:link, .paginator a:visited {
|
||||
padding: 2px 6px;
|
||||
background: #79aec8;
|
||||
background: var(--button-bg);
|
||||
text-decoration: none;
|
||||
color: #fff;
|
||||
color: var(--button-fg);
|
||||
}
|
||||
|
||||
.paginator a.showall {
|
||||
border: none;
|
||||
background: none;
|
||||
color: #5b80b2;
|
||||
color: var(--link-fg);
|
||||
}
|
||||
|
||||
.paginator a.showall:focus, .paginator a.showall:hover {
|
||||
background: none;
|
||||
color: #036;
|
||||
color: var(--link-hover-color);
|
||||
}
|
||||
|
||||
.paginator .end {
|
||||
|
@ -265,7 +264,7 @@
|
|||
|
||||
.paginator a:focus, .paginator a:hover {
|
||||
color: white;
|
||||
background: #036;
|
||||
background: var(--link-hover-color);
|
||||
}
|
||||
|
||||
/* ACTIONS */
|
||||
|
@ -280,22 +279,22 @@
|
|||
}
|
||||
|
||||
#changelist table tbody tr.selected {
|
||||
background-color: #FFFFCC;
|
||||
background-color: var(--selected-row);
|
||||
}
|
||||
|
||||
#changelist .actions {
|
||||
padding: 10px;
|
||||
background: #fff;
|
||||
background: var(--body-bg);
|
||||
border-top: none;
|
||||
border-bottom: none;
|
||||
line-height: 24px;
|
||||
color: #999;
|
||||
color: var(--body-quiet-color);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#changelist .actions.selected {
|
||||
background: #fffccf;
|
||||
border-top: 1px solid #fffee8;
|
||||
#changelist .actions.selected { /* XXX Probably unused? */
|
||||
background: var(--body-bg);
|
||||
border-top: 1px solid var(--body-bg);
|
||||
border-bottom: 1px solid #edecd6;
|
||||
}
|
||||
|
||||
|
@ -305,7 +304,6 @@
|
|||
#changelist .actions span.question {
|
||||
font-size: 13px;
|
||||
margin: 0 0.5em;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#changelist .actions:last-child {
|
||||
|
@ -315,9 +313,8 @@
|
|||
#changelist .actions select {
|
||||
vertical-align: top;
|
||||
height: 24px;
|
||||
background: none;
|
||||
color: #000;
|
||||
border: 1px solid #ccc;
|
||||
color: var(--body-fg);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
padding: 0 0 0 4px;
|
||||
|
@ -326,7 +323,7 @@
|
|||
}
|
||||
|
||||
#changelist .actions select:focus {
|
||||
border-color: #999;
|
||||
border-color: var(--body-quiet-color);
|
||||
}
|
||||
|
||||
#changelist .actions label {
|
||||
|
@ -337,18 +334,18 @@
|
|||
|
||||
#changelist .actions .button {
|
||||
font-size: 13px;
|
||||
border: 1px solid #ccc;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 4px;
|
||||
background: #fff;
|
||||
background: var(--body-bg);
|
||||
box-shadow: 0 -15px 20px -10px rgba(0, 0, 0, 0.15) inset;
|
||||
cursor: pointer;
|
||||
height: 24px;
|
||||
line-height: 1;
|
||||
padding: 4px 8px;
|
||||
margin: 0;
|
||||
color: #333;
|
||||
color: var(--body-fg);
|
||||
}
|
||||
|
||||
#changelist .actions .button:focus, #changelist .actions .button:hover {
|
||||
border-color: #999;
|
||||
border-color: var(--body-quiet-color);
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
overflow: hidden;
|
||||
padding: 10px;
|
||||
font-size: 13px;
|
||||
border-bottom: 1px solid #eee;
|
||||
border-bottom: 1px solid var(--hairline-color);
|
||||
}
|
||||
|
||||
.form-row img, .form-row input {
|
||||
|
@ -22,21 +22,17 @@ form .form-row p {
|
|||
padding-left: 0;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* FORM LABELS */
|
||||
|
||||
label {
|
||||
font-weight: normal;
|
||||
color: #666;
|
||||
color: var(--body-quiet-color);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.required label, label.required {
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
color: var(--body-fg);
|
||||
}
|
||||
|
||||
/* RADIO BUTTONS */
|
||||
|
@ -219,24 +215,24 @@ fieldset.collapsed h2, fieldset.collapsed {
|
|||
}
|
||||
|
||||
fieldset.collapsed {
|
||||
border: 1px solid #eee;
|
||||
border: 1px solid var(--hairline-color);
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
fieldset.collapsed h2 {
|
||||
background: #f8f8f8;
|
||||
color: #666;
|
||||
background: var(--darkened-bg);
|
||||
color: var(--body-quiet-color);
|
||||
}
|
||||
|
||||
fieldset .collapse-toggle {
|
||||
color: #fff;
|
||||
color: var(--header-link-color);
|
||||
}
|
||||
|
||||
fieldset.collapsed .collapse-toggle {
|
||||
background: transparent;
|
||||
display: inline;
|
||||
color: #447e9b;
|
||||
color: var(--link-fg);
|
||||
}
|
||||
|
||||
/* MONOSPACE TEXTAREAS */
|
||||
|
@ -250,8 +246,8 @@ fieldset.monospace textarea {
|
|||
.submit-row {
|
||||
padding: 12px 14px;
|
||||
margin: 0 0 20px;
|
||||
background: #f8f8f8;
|
||||
border: 1px solid #eee;
|
||||
background: var(--darkened-bg);
|
||||
border: 1px solid var(--hairline-color);
|
||||
border-radius: 4px;
|
||||
text-align: right;
|
||||
overflow: hidden;
|
||||
|
@ -283,35 +279,35 @@ body.popup .submit-row {
|
|||
|
||||
.submit-row a.deletelink {
|
||||
display: block;
|
||||
background: #ba2121;
|
||||
background: var(--delete-button-bg);
|
||||
border-radius: 4px;
|
||||
padding: 10px 15px;
|
||||
height: 15px;
|
||||
line-height: 15px;
|
||||
color: #fff;
|
||||
color: var(--button-fg);
|
||||
}
|
||||
|
||||
.submit-row a.closelink {
|
||||
display: inline-block;
|
||||
background: #bbbbbb;
|
||||
background: var(--close-button-bg);
|
||||
border-radius: 4px;
|
||||
padding: 10px 15px;
|
||||
height: 15px;
|
||||
line-height: 15px;
|
||||
margin: 0 0 0 5px;
|
||||
color: #fff;
|
||||
color: var(--button-fg);
|
||||
}
|
||||
|
||||
.submit-row a.deletelink:focus,
|
||||
.submit-row a.deletelink:hover,
|
||||
.submit-row a.deletelink:active {
|
||||
background: #a41515;
|
||||
background: var(--delete-button-hover-bg);
|
||||
}
|
||||
|
||||
.submit-row a.closelink:focus,
|
||||
.submit-row a.closelink:hover,
|
||||
.submit-row a.closelink:active {
|
||||
background: #aaaaaa;
|
||||
background: var(--close-button-hover-bg);
|
||||
}
|
||||
|
||||
/* CUSTOM FORM FIELDS */
|
||||
|
@ -390,12 +386,12 @@ body.popup .submit-row {
|
|||
|
||||
.inline-related h3 {
|
||||
margin: 0;
|
||||
color: #666;
|
||||
color: var(--body-quiet-color);
|
||||
padding: 5px;
|
||||
font-size: 13px;
|
||||
background: #f8f8f8;
|
||||
border-top: 1px solid #eee;
|
||||
border-bottom: 1px solid #eee;
|
||||
background: var(--darkened-bg);
|
||||
border-top: 1px solid var(--hairline-color);
|
||||
border-bottom: 1px solid var(--hairline-color);
|
||||
}
|
||||
|
||||
.inline-related h3 span.delete {
|
||||
|
@ -409,7 +405,7 @@ body.popup .submit-row {
|
|||
|
||||
.inline-related fieldset {
|
||||
margin: 0;
|
||||
background: #fff;
|
||||
background: var(--body-bg);
|
||||
border: none;
|
||||
width: 100%;
|
||||
}
|
||||
|
@ -421,7 +417,7 @@ body.popup .submit-row {
|
|||
text-align: left;
|
||||
font-weight: bold;
|
||||
background: #bcd;
|
||||
color: #fff;
|
||||
color: var(--body-bg);
|
||||
}
|
||||
|
||||
.inline-group .tabular fieldset.module {
|
||||
|
@ -460,7 +456,7 @@ body.popup .submit-row {
|
|||
overflow: hidden;
|
||||
font-size: 9px;
|
||||
font-weight: bold;
|
||||
color: #666;
|
||||
color: var(--body-quiet-color);
|
||||
_width: 700px;
|
||||
}
|
||||
|
||||
|
@ -477,15 +473,15 @@ body.popup .submit-row {
|
|||
|
||||
.inline-group div.add-row,
|
||||
.inline-group .tabular tr.add-row td {
|
||||
color: #666;
|
||||
background: #f8f8f8;
|
||||
color: var(--body-quiet-color);
|
||||
background: var(--darkened-bg);
|
||||
padding: 8px 10px;
|
||||
border-bottom: 1px solid #eee;
|
||||
border-bottom: 1px solid var(--hairline-color);
|
||||
}
|
||||
|
||||
.inline-group .tabular tr.add-row td {
|
||||
padding: 8px 10px;
|
||||
border-bottom: 1px solid #eee;
|
||||
border-bottom: 1px solid var(--hairline-color);
|
||||
}
|
||||
|
||||
.inline-group ul.tools a.add,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* LOGIN FORM */
|
||||
|
||||
.login {
|
||||
background: #f8f8f8;
|
||||
background: var(--darkened-bg);
|
||||
height: auto;
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
|||
}
|
||||
|
||||
.login #header h1 a {
|
||||
color: #fff;
|
||||
color: var(--header-link-color);
|
||||
}
|
||||
|
||||
.login #content {
|
||||
|
@ -24,8 +24,8 @@
|
|||
}
|
||||
|
||||
.login #container {
|
||||
background: #fff;
|
||||
border: 1px solid #eaeaea;
|
||||
background: var(--body-bg);
|
||||
border: 1px solid var(--hairline-color);
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
width: 28em;
|
||||
|
@ -34,44 +34,25 @@
|
|||
height: auto;
|
||||
}
|
||||
|
||||
.login #content-main {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.login .form-row {
|
||||
padding: 4px 0;
|
||||
float: left;
|
||||
width: 100%;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.login .form-row label {
|
||||
padding-right: 0.5em;
|
||||
display: block;
|
||||
line-height: 2em;
|
||||
font-size: 1em;
|
||||
clear: both;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.login .form-row #id_username, .login .form-row #id_password {
|
||||
clear: both;
|
||||
padding: 8px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.login span.help {
|
||||
font-size: 10px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.login .submit-row {
|
||||
clear: both;
|
||||
padding: 1em 0 0 9.4em;
|
||||
padding: 1em 0 0 0;
|
||||
margin: 0;
|
||||
border: none;
|
||||
background: none;
|
||||
text-align: left;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.login .password-reset-link {
|
||||
|
|
|
@ -12,22 +12,23 @@
|
|||
justify-content: center;
|
||||
flex: 0 0 23px;
|
||||
width: 23px;
|
||||
border-right: 1px solid #eaeaea;
|
||||
background-color: #ffffff;
|
||||
border: 0;
|
||||
border-right: 1px solid var(--hairline-color);
|
||||
background-color: var(--body-bg);
|
||||
cursor: pointer;
|
||||
font-size: 20px;
|
||||
color: #447e9b;
|
||||
color: var(--link-fg);
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
[dir="rtl"] .toggle-nav-sidebar {
|
||||
border-left: 1px solid #eaeaea;
|
||||
border-left: 1px solid var(--hairline-color);
|
||||
border-right: 0;
|
||||
}
|
||||
|
||||
.toggle-nav-sidebar:hover,
|
||||
.toggle-nav-sidebar:focus {
|
||||
background-color: #f6f6f6;
|
||||
background-color: var(--darkened-bg);
|
||||
}
|
||||
|
||||
#nav-sidebar {
|
||||
|
@ -36,13 +37,13 @@
|
|||
left: -276px;
|
||||
margin-left: -276px;
|
||||
border-top: 1px solid transparent;
|
||||
border-right: 1px solid #eaeaea;
|
||||
background-color: #ffffff;
|
||||
border-right: 1px solid var(--hairline-color);
|
||||
background-color: var(--body-bg);
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
[dir="rtl"] #nav-sidebar {
|
||||
border-left: 1px solid #eaeaea;
|
||||
border-left: 1px solid var(--hairline-color);
|
||||
border-right: 0;
|
||||
left: 0;
|
||||
margin-left: 0;
|
||||
|
@ -91,12 +92,12 @@
|
|||
|
||||
#nav-sidebar .current-app .section:link,
|
||||
#nav-sidebar .current-app .section:visited {
|
||||
color: #ffc;
|
||||
color: var(--header-color);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#nav-sidebar .current-model {
|
||||
background: #ffc;
|
||||
background: var(--selected-row);
|
||||
}
|
||||
|
||||
.main > #nav-sidebar + .content {
|
||||
|
|
|
@ -140,7 +140,7 @@ input[type="submit"], button {
|
|||
}
|
||||
|
||||
#changelist .actions select {
|
||||
background: #fff;
|
||||
background: var(--body-bg);
|
||||
}
|
||||
|
||||
#changelist .actions .button {
|
||||
|
@ -157,7 +157,7 @@ input[type="submit"], button {
|
|||
}
|
||||
|
||||
#changelist-filter {
|
||||
width: 200px;
|
||||
flex-basis: 200px;
|
||||
}
|
||||
|
||||
.change-list .filtered .results,
|
||||
|
@ -166,7 +166,7 @@ input[type="submit"], button {
|
|||
.filtered .actions,
|
||||
|
||||
#changelist .paginator {
|
||||
border-top-color: #eee;
|
||||
border-top-color: var(--hairline-color); /* XXX Is this used at all? */
|
||||
}
|
||||
|
||||
#changelist .results + .paginator {
|
||||
|
@ -213,7 +213,7 @@ input[type="submit"], button {
|
|||
fieldset .fieldBox + .fieldBox {
|
||||
margin-top: 10px;
|
||||
padding-top: 10px;
|
||||
border-top: 1px solid #eee;
|
||||
border-top: 1px solid var(--hairline-color);
|
||||
}
|
||||
|
||||
textarea {
|
||||
|
@ -399,11 +399,11 @@ input[type="submit"], button {
|
|||
.datetime .timezonewarning {
|
||||
display: block;
|
||||
font-size: 11px;
|
||||
color: #999;
|
||||
color: var(--body-quiet-color);
|
||||
}
|
||||
|
||||
.datetimeshortcuts {
|
||||
color: #ccc;
|
||||
color: var(--border-color); /* XXX Redundant, .datetime span also sets #ccc */
|
||||
}
|
||||
|
||||
.form-row .datetime input.vDateField, .form-row .datetime input.vTimeField {
|
||||
|
@ -655,7 +655,7 @@ input[type="submit"], button {
|
|||
margin-bottom: -3px;
|
||||
}
|
||||
|
||||
form .aligned ul.radiolist li + li {
|
||||
form .aligned ul.radiolist:not(.inline) li + li {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
|
@ -740,7 +740,7 @@ input[type="submit"], button {
|
|||
/* Inlines */
|
||||
|
||||
.inline-group[data-inline-type="stacked"] .inline-related {
|
||||
border: 2px solid #eee;
|
||||
border: 1px solid var(--hairline-color);
|
||||
border-radius: 4px;
|
||||
margin-top: 15px;
|
||||
overflow: auto;
|
||||
|
@ -750,18 +750,19 @@ input[type="submit"], button {
|
|||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.inline-group[data-inline-type="stacked"] .inline-related + .inline-related {
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.inline-group[data-inline-type="stacked"] .inline-related .module {
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.inline-group[data-inline-type="stacked"] .inline-related .module .form-row:last-child {
|
||||
.inline-group[data-inline-type="stacked"] .inline-related .module .form-row {
|
||||
border-top: 1px solid var(--hairline-color);
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.inline-group[data-inline-type="stacked"] .inline-related .module .form-row:first-child {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
.inline-group[data-inline-type="stacked"] .inline-related h3 {
|
||||
padding: 10px;
|
||||
border-top-width: 0;
|
||||
|
@ -791,7 +792,7 @@ input[type="submit"], button {
|
|||
|
||||
.inline-group[data-inline-type="stacked"] div.add-row {
|
||||
margin-top: 15px;
|
||||
border: 1px solid #eee;
|
||||
border: 1px solid var(--hairline-color);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
|
@ -885,9 +886,7 @@ input[type="submit"], button {
|
|||
}
|
||||
|
||||
.login .form-row label {
|
||||
display: block;
|
||||
margin: 0 0 5px;
|
||||
padding: 0;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
|
@ -895,7 +894,7 @@ input[type="submit"], button {
|
|||
padding: 15px 0 0;
|
||||
}
|
||||
|
||||
.login br, .login .submit-row label {
|
||||
.login br {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
@ -963,7 +962,7 @@ input[type="submit"], button {
|
|||
}
|
||||
|
||||
.timelist a {
|
||||
background: #fff;
|
||||
background: var(--body-bg);
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
body {
|
||||
direction: rtl;
|
||||
}
|
||||
|
||||
/* LOGIN */
|
||||
|
||||
.login .form-row {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.login .form-row label {
|
||||
float: right;
|
||||
padding-left: 0.5em;
|
||||
padding-right: 0;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.login .submit-row {
|
||||
clear: both;
|
||||
padding: 1em 9.4em 0 0;
|
||||
}
|
||||
|
||||
/* GLOBAL */
|
||||
|
||||
th {
|
||||
|
@ -119,7 +97,7 @@ thead th.sorted .text {
|
|||
border-left: none;
|
||||
padding-left: 10px;
|
||||
margin-left: 0;
|
||||
border-right: 5px solid #eaeaea;
|
||||
border-right: 5px solid var(--hairline-color);
|
||||
padding-right: 10px;
|
||||
margin-right: -15px;
|
||||
}
|
||||
|
|
|
@ -22,26 +22,25 @@
|
|||
}
|
||||
|
||||
.selector-available h2, .selector-chosen h2 {
|
||||
border: 1px solid #ccc;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 4px 4px 0 0;
|
||||
}
|
||||
|
||||
.selector-chosen h2 {
|
||||
background: #79aec8;
|
||||
color: #fff;
|
||||
background: var(--primary);
|
||||
color: var(--header-link-color);
|
||||
}
|
||||
|
||||
.selector .selector-available h2 {
|
||||
background: #f8f8f8;
|
||||
color: #666;
|
||||
background: var(--darkened-bg);
|
||||
color: var(--body-quiet-color);
|
||||
}
|
||||
|
||||
.selector .selector-filter {
|
||||
background: white;
|
||||
border: 1px solid #ccc;
|
||||
border: 1px solid var(--border-color);
|
||||
border-width: 0 1px;
|
||||
padding: 8px;
|
||||
color: #999;
|
||||
color: var(--body-quiet-color);
|
||||
font-size: 10px;
|
||||
margin: 0;
|
||||
text-align: left;
|
||||
|
@ -66,7 +65,7 @@
|
|||
.selector ul.selector-chooser {
|
||||
float: left;
|
||||
width: 22px;
|
||||
background-color: #eee;
|
||||
background-color: var(--selected-bg);
|
||||
border-radius: 10px;
|
||||
margin: 10em 5px 0 5px;
|
||||
padding: 0;
|
||||
|
@ -91,7 +90,7 @@
|
|||
text-indent: -3000px;
|
||||
overflow: hidden;
|
||||
cursor: default;
|
||||
opacity: 0.3;
|
||||
opacity: 0.55;
|
||||
}
|
||||
|
||||
.active.selector-add, .active.selector-remove {
|
||||
|
@ -126,14 +125,14 @@ a.selector-chooseall, a.selector-clearall {
|
|||
overflow: hidden;
|
||||
font-weight: bold;
|
||||
line-height: 16px;
|
||||
color: #666;
|
||||
color: var(--body-quiet-color);
|
||||
text-decoration: none;
|
||||
opacity: 0.3;
|
||||
opacity: 0.55;
|
||||
}
|
||||
|
||||
a.active.selector-chooseall:focus, a.active.selector-clearall:focus,
|
||||
a.active.selector-chooseall:hover, a.active.selector-clearall:hover {
|
||||
color: #447e9b;
|
||||
color: var(--link-fg);
|
||||
}
|
||||
|
||||
a.active.selector-chooseall, a.active.selector-clearall {
|
||||
|
@ -261,7 +260,7 @@ p.datetime {
|
|||
line-height: 20px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: #666;
|
||||
color: var(--body-quiet-color);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
@ -269,7 +268,7 @@ p.datetime {
|
|||
white-space: nowrap;
|
||||
font-weight: normal;
|
||||
font-size: 11px;
|
||||
color: #ccc;
|
||||
color: var(--body-quiet-color);
|
||||
}
|
||||
|
||||
.datetime input, .form-row .datetime input.vDateField, .form-row .datetime input.vTimeField {
|
||||
|
@ -313,7 +312,7 @@ table p.datetime {
|
|||
|
||||
.timezonewarning {
|
||||
font-size: 11px;
|
||||
color: #999;
|
||||
color: var(--body-quiet-color);
|
||||
}
|
||||
|
||||
/* URL */
|
||||
|
@ -322,7 +321,7 @@ p.url {
|
|||
line-height: 20px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: #666;
|
||||
color: var(--body-quiet-color);
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
@ -337,7 +336,7 @@ p.file-upload {
|
|||
line-height: 20px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: #666;
|
||||
color: var(--body-quiet-color);
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
@ -355,7 +354,7 @@ p.file-upload {
|
|||
}
|
||||
|
||||
span.clearable-file-input label {
|
||||
color: #333;
|
||||
color: var(--body-fg);
|
||||
font-size: 11px;
|
||||
display: inline;
|
||||
float: none;
|
||||
|
@ -368,8 +367,9 @@ span.clearable-file-input label {
|
|||
font-size: 12px;
|
||||
width: 19em;
|
||||
text-align: center;
|
||||
background: white;
|
||||
border: 1px solid #ddd;
|
||||
background: var(--body-bg);
|
||||
color: var(--body-fg);
|
||||
border: 1px solid var(--hairline-color);
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
|
||||
overflow: hidden;
|
||||
|
@ -397,20 +397,20 @@ span.clearable-file-input label {
|
|||
margin: 0;
|
||||
text-align: center;
|
||||
border-top: none;
|
||||
background: #f5dd5d;
|
||||
font-weight: 700;
|
||||
font-size: 12px;
|
||||
color: #333;
|
||||
background: var(--accent);
|
||||
}
|
||||
|
||||
.calendar th {
|
||||
padding: 8px 5px;
|
||||
background: #f8f8f8;
|
||||
border-bottom: 1px solid #ddd;
|
||||
background: var(--darkened-bg);
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
font-weight: 400;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
color: #666;
|
||||
color: var(--body-quiet-color);
|
||||
}
|
||||
|
||||
.calendar td {
|
||||
|
@ -418,17 +418,17 @@ span.clearable-file-input label {
|
|||
font-size: 12px;
|
||||
text-align: center;
|
||||
padding: 0;
|
||||
border-top: 1px solid #eee;
|
||||
border-top: 1px solid var(--hairline-color);
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.calendar td.selected a {
|
||||
background: #79aec8;
|
||||
color: #fff;
|
||||
background: var(--primary);
|
||||
color: var(--button-fg);
|
||||
}
|
||||
|
||||
.calendar td.nonday {
|
||||
background: #f8f8f8;
|
||||
background: var(--darkened-bg);
|
||||
}
|
||||
|
||||
.calendar td.today a {
|
||||
|
@ -440,17 +440,17 @@ span.clearable-file-input label {
|
|||
font-weight: 400;
|
||||
padding: 6px;
|
||||
text-decoration: none;
|
||||
color: #444;
|
||||
color: var(--body-quiet-color);
|
||||
}
|
||||
|
||||
.calendar td a:focus, .timelist a:focus,
|
||||
.calendar td a:hover, .timelist a:hover {
|
||||
background: #79aec8;
|
||||
background: var(--primary);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.calendar td a:active, .timelist a:active {
|
||||
background: #417690;
|
||||
background: var(--header-bg);
|
||||
color: white;
|
||||
}
|
||||
|
||||
|
@ -464,16 +464,16 @@ span.clearable-file-input label {
|
|||
|
||||
.calendarnav a:link, #calendarnav a:visited,
|
||||
#calendarnav a:focus, #calendarnav a:hover {
|
||||
color: #999;
|
||||
color: var(--body-quiet-color);
|
||||
}
|
||||
|
||||
.calendar-shortcuts {
|
||||
background: white;
|
||||
background: var(--body-bg);
|
||||
color: var(--body-quiet-color);
|
||||
font-size: 11px;
|
||||
line-height: 11px;
|
||||
border-top: 1px solid #eee;
|
||||
border-top: 1px solid var(--hairline-color);
|
||||
padding: 8px 0;
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.calendarbox .calendarnav-previous, .calendarbox .calendarnav-next {
|
||||
|
@ -511,8 +511,8 @@ span.clearable-file-input label {
|
|||
padding: 4px 0;
|
||||
font-size: 12px;
|
||||
background: #eee;
|
||||
border-top: 1px solid #ddd;
|
||||
color: #333;
|
||||
border-top: 1px solid var(--border-color);
|
||||
color: var(--body-fg);
|
||||
}
|
||||
|
||||
.calendar-cancel:focus, .calendar-cancel:hover {
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
redisplay: function(id) {
|
||||
// Repopulate HTML select box from cache
|
||||
const box = document.getElementById(id);
|
||||
const scroll_value_from_top = box.scrollTop;
|
||||
box.innerHTML = '';
|
||||
for (const node of SelectBox.cache[id]) {
|
||||
if (node.displayed) {
|
||||
|
@ -22,6 +23,7 @@
|
|||
box.appendChild(new_option);
|
||||
}
|
||||
}
|
||||
box.scrollTop = scroll_value_from_top;
|
||||
},
|
||||
filter: function(id, text) {
|
||||
// Redisplay the HTML select box, displaying only the choices containing ALL
|
||||
|
@ -31,7 +33,7 @@
|
|||
node.displayed = 1;
|
||||
const node_text = node.text.toLowerCase();
|
||||
for (const token of tokens) {
|
||||
if (node_text.indexOf(token) === -1) {
|
||||
if (!node_text.includes(token)) {
|
||||
node.displayed = 0;
|
||||
break; // Once the first token isn't found we're done
|
||||
}
|
||||
|
|
|
@ -1,154 +1,201 @@
|
|||
/*global gettext, interpolate, ngettext*/
|
||||
'use strict';
|
||||
{
|
||||
const $ = django.jQuery;
|
||||
let lastChecked;
|
||||
function show(selector) {
|
||||
document.querySelectorAll(selector).forEach(function(el) {
|
||||
el.classList.remove('hidden');
|
||||
});
|
||||
}
|
||||
|
||||
$.fn.actions = function(opts) {
|
||||
const options = $.extend({}, $.fn.actions.defaults, opts);
|
||||
const actionCheckboxes = $(this);
|
||||
let list_editable_changed = false;
|
||||
const showQuestion = function() {
|
||||
$(options.acrossClears).hide();
|
||||
$(options.acrossQuestions).show();
|
||||
$(options.allContainer).hide();
|
||||
},
|
||||
showClear = function() {
|
||||
$(options.acrossClears).show();
|
||||
$(options.acrossQuestions).hide();
|
||||
$(options.actionContainer).toggleClass(options.selectedClass);
|
||||
$(options.allContainer).show();
|
||||
$(options.counterContainer).hide();
|
||||
},
|
||||
reset = function() {
|
||||
$(options.acrossClears).hide();
|
||||
$(options.acrossQuestions).hide();
|
||||
$(options.allContainer).hide();
|
||||
$(options.counterContainer).show();
|
||||
},
|
||||
clearAcross = function() {
|
||||
reset();
|
||||
$(options.acrossInput).val(0);
|
||||
$(options.actionContainer).removeClass(options.selectedClass);
|
||||
},
|
||||
checker = function(checked) {
|
||||
if (checked) {
|
||||
showQuestion();
|
||||
} else {
|
||||
reset();
|
||||
}
|
||||
$(actionCheckboxes).prop("checked", checked)
|
||||
.parent().parent().toggleClass(options.selectedClass, checked);
|
||||
},
|
||||
updateCounter = function() {
|
||||
const sel = $(actionCheckboxes).filter(":checked").length;
|
||||
// data-actions-icnt is defined in the generated HTML
|
||||
// and contains the total amount of objects in the queryset
|
||||
const actions_icnt = $('.action-counter').data('actionsIcnt');
|
||||
$(options.counterContainer).html(interpolate(
|
||||
ngettext('%(sel)s of %(cnt)s selected', '%(sel)s of %(cnt)s selected', sel), {
|
||||
sel: sel,
|
||||
cnt: actions_icnt
|
||||
}, true));
|
||||
$(options.allToggle).prop("checked", function() {
|
||||
let value;
|
||||
if (sel === actionCheckboxes.length) {
|
||||
value = true;
|
||||
showQuestion();
|
||||
} else {
|
||||
value = false;
|
||||
clearAcross();
|
||||
}
|
||||
return value;
|
||||
});
|
||||
};
|
||||
// Show counter by default
|
||||
$(options.counterContainer).show();
|
||||
// Check state of checkboxes and reinit state if needed
|
||||
$(this).filter(":checked").each(function(i) {
|
||||
$(this).parent().parent().toggleClass(options.selectedClass);
|
||||
updateCounter();
|
||||
if ($(options.acrossInput).val() === 1) {
|
||||
showClear();
|
||||
}
|
||||
function hide(selector) {
|
||||
document.querySelectorAll(selector).forEach(function(el) {
|
||||
el.classList.add('hidden');
|
||||
});
|
||||
$(options.allToggle).show().on('click', function() {
|
||||
checker($(this).prop("checked"));
|
||||
updateCounter();
|
||||
}
|
||||
|
||||
function showQuestion(options) {
|
||||
hide(options.acrossClears);
|
||||
show(options.acrossQuestions);
|
||||
hide(options.allContainer);
|
||||
}
|
||||
|
||||
function showClear(options) {
|
||||
show(options.acrossClears);
|
||||
hide(options.acrossQuestions);
|
||||
document.querySelector(options.actionContainer).classList.remove(options.selectedClass);
|
||||
show(options.allContainer);
|
||||
hide(options.counterContainer);
|
||||
}
|
||||
|
||||
function reset(options) {
|
||||
hide(options.acrossClears);
|
||||
hide(options.acrossQuestions);
|
||||
hide(options.allContainer);
|
||||
show(options.counterContainer);
|
||||
}
|
||||
|
||||
function clearAcross(options) {
|
||||
reset(options);
|
||||
const acrossInputs = document.querySelectorAll(options.acrossInput);
|
||||
acrossInputs.forEach(function(acrossInput) {
|
||||
acrossInput.value = 0;
|
||||
});
|
||||
$("a", options.acrossQuestions).on('click', function(event) {
|
||||
event.preventDefault();
|
||||
$(options.acrossInput).val(1);
|
||||
showClear();
|
||||
document.querySelector(options.actionContainer).classList.remove(options.selectedClass);
|
||||
}
|
||||
|
||||
function checker(actionCheckboxes, options, checked) {
|
||||
if (checked) {
|
||||
showQuestion(options);
|
||||
} else {
|
||||
reset(options);
|
||||
}
|
||||
actionCheckboxes.forEach(function(el) {
|
||||
el.checked = checked;
|
||||
el.closest('tr').classList.toggle(options.selectedClass, checked);
|
||||
});
|
||||
$("a", options.acrossClears).on('click', function(event) {
|
||||
event.preventDefault();
|
||||
$(options.allToggle).prop("checked", false);
|
||||
clearAcross();
|
||||
checker(0);
|
||||
updateCounter();
|
||||
});
|
||||
lastChecked = null;
|
||||
$(actionCheckboxes).on('click', function(event) {
|
||||
if (!event) { event = window.event; }
|
||||
const target = event.target ? event.target : event.srcElement;
|
||||
if (lastChecked && $.data(lastChecked) !== $.data(target) && event.shiftKey === true) {
|
||||
let inrange = false;
|
||||
$(lastChecked).prop("checked", target.checked)
|
||||
.parent().parent().toggleClass(options.selectedClass, target.checked);
|
||||
$(actionCheckboxes).each(function() {
|
||||
if ($.data(this) === $.data(lastChecked) || $.data(this) === $.data(target)) {
|
||||
inrange = (inrange) ? false : true;
|
||||
}
|
||||
if (inrange) {
|
||||
$(this).prop("checked", target.checked)
|
||||
.parent().parent().toggleClass(options.selectedClass, target.checked);
|
||||
}
|
||||
});
|
||||
}
|
||||
$(target).parent().parent().toggleClass(options.selectedClass, target.checked);
|
||||
lastChecked = target;
|
||||
updateCounter();
|
||||
});
|
||||
$('form#changelist-form table#result_list tr').on('change', 'td:gt(0) :input', function() {
|
||||
list_editable_changed = true;
|
||||
});
|
||||
$('form#changelist-form button[name="index"]').on('click', function(event) {
|
||||
if (list_editable_changed) {
|
||||
return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost."));
|
||||
}
|
||||
});
|
||||
$('form#changelist-form input[name="_save"]').on('click', function(event) {
|
||||
let action_changed = false;
|
||||
$('select option:selected', options.actionContainer).each(function() {
|
||||
if ($(this).val()) {
|
||||
action_changed = true;
|
||||
}
|
||||
});
|
||||
if (action_changed) {
|
||||
if (list_editable_changed) {
|
||||
return confirm(gettext("You have selected an action, but you haven’t saved your changes to individual fields yet. Please click OK to save. You’ll need to re-run the action."));
|
||||
} else {
|
||||
return confirm(gettext("You have selected an action, and you haven’t made any changes on individual fields. You’re probably looking for the Go button rather than the Save button."));
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
/* Setup plugin defaults */
|
||||
$.fn.actions.defaults = {
|
||||
}
|
||||
|
||||
function updateCounter(actionCheckboxes, options) {
|
||||
const sel = Array.from(actionCheckboxes).filter(function(el) {
|
||||
return el.checked;
|
||||
}).length;
|
||||
const counter = document.querySelector(options.counterContainer);
|
||||
// data-actions-icnt is defined in the generated HTML
|
||||
// and contains the total amount of objects in the queryset
|
||||
const actions_icnt = Number(counter.dataset.actionsIcnt);
|
||||
counter.textContent = interpolate(
|
||||
ngettext('%(sel)s of %(cnt)s selected', '%(sel)s of %(cnt)s selected', sel), {
|
||||
sel: sel,
|
||||
cnt: actions_icnt
|
||||
}, true);
|
||||
const allToggle = document.getElementById(options.allToggleId);
|
||||
allToggle.checked = sel === actionCheckboxes.length;
|
||||
if (allToggle.checked) {
|
||||
showQuestion(options);
|
||||
} else {
|
||||
clearAcross(options);
|
||||
}
|
||||
}
|
||||
|
||||
const defaults = {
|
||||
actionContainer: "div.actions",
|
||||
counterContainer: "span.action-counter",
|
||||
allContainer: "div.actions span.all",
|
||||
acrossInput: "div.actions input.select-across",
|
||||
acrossQuestions: "div.actions span.question",
|
||||
acrossClears: "div.actions span.clear",
|
||||
allToggle: "#action-toggle",
|
||||
allToggleId: "action-toggle",
|
||||
selectedClass: "selected"
|
||||
};
|
||||
$(document).ready(function() {
|
||||
const $actionsEls = $('tr input.action-select');
|
||||
if ($actionsEls.length > 0) {
|
||||
$actionsEls.actions();
|
||||
|
||||
window.Actions = function(actionCheckboxes, options) {
|
||||
options = Object.assign({}, defaults, options);
|
||||
let list_editable_changed = false;
|
||||
let lastChecked = null;
|
||||
let shiftPressed = false;
|
||||
|
||||
document.addEventListener('keydown', (event) => {
|
||||
shiftPressed = event.shiftKey;
|
||||
});
|
||||
|
||||
document.addEventListener('keyup', (event) => {
|
||||
shiftPressed = event.shiftKey;
|
||||
});
|
||||
|
||||
document.getElementById(options.allToggleId).addEventListener('click', function(event) {
|
||||
checker(actionCheckboxes, options, this.checked);
|
||||
updateCounter(actionCheckboxes, options);
|
||||
});
|
||||
|
||||
document.querySelectorAll(options.acrossQuestions + " a").forEach(function(el) {
|
||||
el.addEventListener('click', function(event) {
|
||||
event.preventDefault();
|
||||
const acrossInputs = document.querySelectorAll(options.acrossInput);
|
||||
acrossInputs.forEach(function(acrossInput) {
|
||||
acrossInput.value = 1;
|
||||
});
|
||||
showClear(options);
|
||||
});
|
||||
});
|
||||
|
||||
document.querySelectorAll(options.acrossClears + " a").forEach(function(el) {
|
||||
el.addEventListener('click', function(event) {
|
||||
event.preventDefault();
|
||||
document.getElementById(options.allToggleId).checked = false;
|
||||
clearAcross(options);
|
||||
checker(actionCheckboxes, options, false);
|
||||
updateCounter(actionCheckboxes, options);
|
||||
});
|
||||
});
|
||||
|
||||
function affectedCheckboxes(target, withModifier) {
|
||||
const multiSelect = (lastChecked && withModifier && lastChecked !== target);
|
||||
if (!multiSelect) {
|
||||
return [target];
|
||||
}
|
||||
const checkboxes = Array.from(actionCheckboxes);
|
||||
const targetIndex = checkboxes.findIndex(el => el === target);
|
||||
const lastCheckedIndex = checkboxes.findIndex(el => el === lastChecked);
|
||||
const startIndex = Math.min(targetIndex, lastCheckedIndex);
|
||||
const endIndex = Math.max(targetIndex, lastCheckedIndex);
|
||||
const filtered = checkboxes.filter((el, index) => (startIndex <= index) && (index <= endIndex));
|
||||
return filtered;
|
||||
};
|
||||
|
||||
Array.from(document.getElementById('result_list').tBodies).forEach(function(el) {
|
||||
el.addEventListener('change', function(event) {
|
||||
const target = event.target;
|
||||
if (target.classList.contains('action-select')) {
|
||||
const checkboxes = affectedCheckboxes(target, shiftPressed);
|
||||
checker(checkboxes, options, target.checked);
|
||||
updateCounter(actionCheckboxes, options);
|
||||
lastChecked = target;
|
||||
} else {
|
||||
list_editable_changed = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
document.querySelector('#changelist-form button[name=index]').addEventListener('click', function() {
|
||||
if (list_editable_changed) {
|
||||
const confirmed = confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost."));
|
||||
if (!confirmed) {
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const el = document.querySelector('#changelist-form input[name=_save]');
|
||||
// The button does not exist if no fields are editable.
|
||||
if (el) {
|
||||
el.addEventListener('click', function(event) {
|
||||
if (document.querySelector('[name=action]').value) {
|
||||
const text = list_editable_changed
|
||||
? gettext("You have selected an action, but you haven’t saved your changes to individual fields yet. Please click OK to save. You’ll need to re-run the action.")
|
||||
: gettext("You have selected an action, and you haven’t made any changes on individual fields. You’re probably looking for the Go button rather than the Save button.");
|
||||
if (!confirm(text)) {
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Call function fn when the DOM is loaded and ready. If it is already
|
||||
// loaded, call the function now.
|
||||
// http://youmightnotneedjquery.com/#ready
|
||||
function ready(fn) {
|
||||
if (document.readyState !== 'loading') {
|
||||
fn();
|
||||
} else {
|
||||
document.addEventListener('DOMContentLoaded', fn);
|
||||
}
|
||||
}
|
||||
|
||||
ready(function() {
|
||||
const actionsEls = document.querySelectorAll('tr input.action-select');
|
||||
if (actionsEls.length > 0) {
|
||||
Actions(actionsEls);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
timezoneWarningClass: 'timezonewarning', // class of the warning for timezone mismatch
|
||||
timezoneOffset: 0,
|
||||
init: function() {
|
||||
const body = document.getElementsByTagName('body')[0];
|
||||
const serverOffset = body.dataset.adminUtcOffset;
|
||||
const serverOffset = document.body.dataset.adminUtcOffset;
|
||||
if (serverOffset) {
|
||||
const localOffset = new Date().getTimezoneOffset() * -60;
|
||||
DateTimeShortcuts.timezoneOffset = localOffset - serverOffset;
|
||||
|
@ -48,8 +47,7 @@
|
|||
},
|
||||
// Return the current time while accounting for the server timezone.
|
||||
now: function() {
|
||||
const body = document.getElementsByTagName('body')[0];
|
||||
const serverOffset = body.dataset.adminUtcOffset;
|
||||
const serverOffset = document.body.dataset.adminUtcOffset;
|
||||
if (serverOffset) {
|
||||
const localNow = new Date();
|
||||
const localOffset = localNow.getTimezoneOffset() * -60;
|
||||
|
|
|
@ -7,13 +7,9 @@
|
|||
|
||||
function showAdminPopup(triggeringLink, name_regexp, add_popup) {
|
||||
const name = triggeringLink.id.replace(name_regexp, '');
|
||||
let href = triggeringLink.href;
|
||||
const href = new URL(triggeringLink.href);
|
||||
if (add_popup) {
|
||||
if (href.indexOf('?') === -1) {
|
||||
href += '?_popup=1';
|
||||
} else {
|
||||
href += '&_popup=1';
|
||||
}
|
||||
href.searchParams.set('_popup', 1);
|
||||
}
|
||||
const win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes');
|
||||
win.focus();
|
||||
|
|
|
@ -7,7 +7,10 @@
|
|||
data: function(params) {
|
||||
return {
|
||||
term: params.term,
|
||||
page: params.page
|
||||
page: params.page,
|
||||
app_label: $element.data('app-label'),
|
||||
model_name: $element.data('model-name'),
|
||||
field_name: $element.data('field-name')
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,20 @@ depends on core.js for utility functions like removeChildren or quickElement
|
|||
gettext('November'),
|
||||
gettext('December')
|
||||
],
|
||||
monthsOfYearAbbrev: [
|
||||
pgettext('abbrev. month January', 'Jan'),
|
||||
pgettext('abbrev. month February', 'Feb'),
|
||||
pgettext('abbrev. month March', 'Mar'),
|
||||
pgettext('abbrev. month April', 'Apr'),
|
||||
pgettext('abbrev. month May', 'May'),
|
||||
pgettext('abbrev. month June', 'Jun'),
|
||||
pgettext('abbrev. month July', 'Jul'),
|
||||
pgettext('abbrev. month August', 'Aug'),
|
||||
pgettext('abbrev. month September', 'Sep'),
|
||||
pgettext('abbrev. month October', 'Oct'),
|
||||
pgettext('abbrev. month November', 'Nov'),
|
||||
pgettext('abbrev. month December', 'Dec')
|
||||
],
|
||||
daysOfWeek: [
|
||||
pgettext('one letter Sunday', 'S'),
|
||||
pgettext('one letter Monday', 'M'),
|
||||
|
|
|
@ -14,10 +14,11 @@
|
|||
ready(function() {
|
||||
function handleClick(event) {
|
||||
event.preventDefault();
|
||||
if (window.location.search.indexOf('&_popup=1') === -1) {
|
||||
window.history.back(); // Go back if not a popup.
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
if (params.has('_popup')) {
|
||||
window.close(); // Close the popup.
|
||||
} else {
|
||||
window.close(); // Otherwise, close the popup.
|
||||
window.history.back(); // Otherwise, go back.
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -85,6 +85,12 @@ function findPosY(obj) {
|
|||
return (this.getSeconds() < 10) ? '0' + this.getSeconds() : this.getSeconds();
|
||||
};
|
||||
|
||||
Date.prototype.getAbbrevMonthName = function() {
|
||||
return typeof window.CalendarNamespace === "undefined"
|
||||
? this.getTwoDigitMonth()
|
||||
: window.CalendarNamespace.monthsOfYearAbbrev[this.getMonth()];
|
||||
};
|
||||
|
||||
Date.prototype.getFullMonthName = function() {
|
||||
return typeof window.CalendarNamespace === "undefined"
|
||||
? this.getTwoDigitMonth()
|
||||
|
@ -93,6 +99,7 @@ function findPosY(obj) {
|
|||
|
||||
Date.prototype.strftime = function(format) {
|
||||
const fields = {
|
||||
b: this.getAbbrevMonthName(),
|
||||
B: this.getFullMonthName(),
|
||||
c: this.toString(),
|
||||
d: this.getTwoDigitDate(),
|
||||
|
|
|
@ -134,8 +134,7 @@
|
|||
for (const lookup of ALL_DOWNCODE_MAPS) {
|
||||
Object.assign(Downcoder.map, lookup);
|
||||
}
|
||||
Downcoder.chars = Object.keys(Downcoder.map);
|
||||
Downcoder.regex = new RegExp(Downcoder.chars.join('|'), 'g');
|
||||
Downcoder.regex = new RegExp(Object.keys(Downcoder.map).join('|'), 'g');
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -149,23 +148,9 @@
|
|||
|
||||
function URLify(s, num_chars, allowUnicode) {
|
||||
// changes, e.g., "Petty theft" to "petty-theft"
|
||||
// remove all these words from the string before urlifying
|
||||
if (!allowUnicode) {
|
||||
s = downcode(s);
|
||||
}
|
||||
const hasUnicodeChars = /[^\u0000-\u007f]/.test(s);
|
||||
// Remove English words only if the string contains ASCII (English)
|
||||
// characters.
|
||||
if (!hasUnicodeChars) {
|
||||
const removeList = [
|
||||
"a", "an", "as", "at", "before", "but", "by", "for", "from",
|
||||
"is", "in", "into", "like", "of", "off", "on", "onto", "per",
|
||||
"since", "than", "the", "this", "that", "to", "up", "via",
|
||||
"with"
|
||||
];
|
||||
const r = new RegExp('\\b(' + removeList.join('|') + ')\\b', 'gi');
|
||||
s = s.replace(r, '');
|
||||
}
|
||||
s = s.toLowerCase(); // convert to lowercase
|
||||
// if downcode doesn't hit, the char will be stripped here
|
||||
if (allowUnicode) {
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,9 +0,0 @@
|
|||
|
||||
|
||||
.custom-article {
|
||||
border-style: solid;
|
||||
border-color: gray;
|
||||
border-width: 1px;
|
||||
padding: 5px;
|
||||
border-left: 3px solid SteelBlue;
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 754 B |
|
@ -1 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M19.07,4.93C17.22,3 14.66,1.96 12,2C9.34,1.96 6.79,3 4.94,4.93C3,6.78 1.96,9.34 2,12C1.96,14.66 3,17.21 4.93,19.06C6.78,21 9.34,22.04 12,22C14.66,22.04 17.21,21 19.06,19.07C21,17.22 22.04,14.66 22,12C22.04,9.34 21,6.78 19.07,4.93M17,12V18H13.5V13H10.5V18H7V12H5L12,5L19.5,12H17Z" /></svg>
|
Before Width: | Height: | Size: 573 B |
File diff suppressed because one or more lines are too long
|
@ -1,48 +0,0 @@
|
|||
|
||||
|
||||
$(function() {
|
||||
$('.downmovie').click(function(event) {
|
||||
var id = $(this).attr('id')
|
||||
var href = $(this).attr('href')
|
||||
var hc = window.location.href
|
||||
var url = '../addcount/' + id
|
||||
|
||||
if(hc.search('director')){
|
||||
url = '../../addcount/' + id
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
$.ajax({
|
||||
url: url,
|
||||
success : function(data){
|
||||
$('#down' + id).text(data);
|
||||
}
|
||||
})
|
||||
|
||||
var msg = 'Gracias al "honorable" poder legislativo de mi país, ya no es posible compartir nada, contactanos en nuestro canal de Telegram si tienes dudas: @mauflix'
|
||||
alert(msg);
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
function director_change(){
|
||||
var directors = document.getElementById('directors')
|
||||
if(directors.selectedIndex){
|
||||
name = directors.options[directors.selectedIndex].value
|
||||
window.location.href = '/movies/director/' + name
|
||||
}else{
|
||||
window.location.href = '/movies'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function search_movie(){
|
||||
var search = document.getElementById('search')
|
||||
window.location.href = '/movies/' + search.value
|
||||
}
|
||||
|
||||
|
||||
function search_key_press(ev){
|
||||
alert(ev.keyCode)
|
||||
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Before Width: | Height: | Size: 434 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,6 +0,0 @@
|
|||
/*!
|
||||
Autosize 3.0.15
|
||||
license: MIT
|
||||
http://www.jacklmoore.com/autosize
|
||||
*/
|
||||
!function(e,t){if("function"==typeof define&&define.amd)define(["exports","module"],t);else if("undefined"!=typeof exports&&"undefined"!=typeof module)t(exports,module);else{var n={exports:{}};t(n.exports,n),e.autosize=n.exports}}(this,function(e,t){"use strict";function n(e){function t(){var t=window.getComputedStyle(e,null);p=t.overflowY,"vertical"===t.resize?e.style.resize="none":"both"===t.resize&&(e.style.resize="horizontal"),c="content-box"===t.boxSizing?-(parseFloat(t.paddingTop)+parseFloat(t.paddingBottom)):parseFloat(t.borderTopWidth)+parseFloat(t.borderBottomWidth),isNaN(c)&&(c=0),i()}function n(t){var n=e.style.width;e.style.width="0px",e.offsetWidth,e.style.width=n,p=t,f&&(e.style.overflowY=t),o()}function o(){var t=window.pageYOffset,n=document.body.scrollTop,o=e.style.height;e.style.height="auto";var i=e.scrollHeight+c;return 0===e.scrollHeight?void(e.style.height=o):(e.style.height=i+"px",v=e.clientWidth,document.documentElement.scrollTop=t,void(document.body.scrollTop=n))}function i(){var t=e.style.height;o();var i=window.getComputedStyle(e,null);if(i.height!==e.style.height?"visible"!==p&&n("visible"):"hidden"!==p&&n("hidden"),t!==e.style.height){var r=d("autosize:resized");e.dispatchEvent(r)}}var s=void 0===arguments[1]?{}:arguments[1],a=s.setOverflowX,l=void 0===a?!0:a,u=s.setOverflowY,f=void 0===u?!0:u;if(e&&e.nodeName&&"TEXTAREA"===e.nodeName&&!r.has(e)){var c=null,p=null,v=e.clientWidth,h=function(){e.clientWidth!==v&&i()},y=function(t){window.removeEventListener("resize",h,!1),e.removeEventListener("input",i,!1),e.removeEventListener("keyup",i,!1),e.removeEventListener("autosize:destroy",y,!1),e.removeEventListener("autosize:update",i,!1),r["delete"](e),Object.keys(t).forEach(function(n){e.style[n]=t[n]})}.bind(e,{height:e.style.height,resize:e.style.resize,overflowY:e.style.overflowY,overflowX:e.style.overflowX,wordWrap:e.style.wordWrap});e.addEventListener("autosize:destroy",y,!1),"onpropertychange"in e&&"oninput"in e&&e.addEventListener("keyup",i,!1),window.addEventListener("resize",h,!1),e.addEventListener("input",i,!1),e.addEventListener("autosize:update",i,!1),r.add(e),l&&(e.style.overflowX="hidden",e.style.wordWrap="break-word"),t()}}function o(e){if(e&&e.nodeName&&"TEXTAREA"===e.nodeName){var t=d("autosize:destroy");e.dispatchEvent(t)}}function i(e){if(e&&e.nodeName&&"TEXTAREA"===e.nodeName){var t=d("autosize:update");e.dispatchEvent(t)}}var r="function"==typeof Set?new Set:function(){var e=[];return{has:function(t){return Boolean(e.indexOf(t)>-1)},add:function(t){e.push(t)},"delete":function(t){e.splice(e.indexOf(t),1)}}}(),d=function(e){return new Event(e)};try{new Event("test")}catch(s){d=function(e){var t=document.createEvent("Event");return t.initEvent(e,!0,!1),t}}var a=null;"undefined"==typeof window||"function"!=typeof window.getComputedStyle?(a=function(e){return e},a.destroy=function(e){return e},a.update=function(e){return e}):(a=function(e,t){return e&&Array.prototype.forEach.call(e.length?e:[e],function(e){return n(e,t)}),e},a.destroy=function(e){return e&&Array.prototype.forEach.call(e.length?e:[e],o),e},a.update=function(e){return e&&Array.prototype.forEach.call(e.length?e:[e],i),e}),t.exports=a});
|
|
@ -1,250 +0,0 @@
|
|||
Suit = {};
|
||||
window.Suit = Suit;
|
||||
|
||||
(function ($) {
|
||||
if (!$)
|
||||
return;
|
||||
|
||||
Suit.$ = $;
|
||||
|
||||
// Register callbacks to perform after inline has been added
|
||||
Suit.after_inline = function () {
|
||||
var functions = {};
|
||||
var register = function (fn_name, fn_callback) {
|
||||
functions[fn_name] = fn_callback;
|
||||
};
|
||||
|
||||
var run = function (inline_prefix, row) {
|
||||
for (var fn_name in functions) {
|
||||
functions[fn_name](inline_prefix, row);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
register: register,
|
||||
run: run
|
||||
};
|
||||
}();
|
||||
|
||||
Suit.ListActionsToggle = function () {
|
||||
var $topActions;
|
||||
|
||||
var init = function () {
|
||||
$(document).ready(function () {
|
||||
$topActions = $('.results').parent().find('.actions').eq(0);
|
||||
if (!$topActions.length)
|
||||
return;
|
||||
|
||||
$("tr input.action-select, #action-toggle").on('click', checkIfSelected);
|
||||
});
|
||||
};
|
||||
|
||||
var checkIfSelected = function () {
|
||||
if ($('tr.selected').length) {
|
||||
$topActions.slideDown('fast');
|
||||
} else {
|
||||
$topActions.slideUp('fast');
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
init: init
|
||||
}
|
||||
|
||||
}();
|
||||
|
||||
|
||||
Suit.FixedBar = function () {
|
||||
var didScroll = false, $fixedItem, $fixedItemParent, $win, $body,
|
||||
itemOffset,
|
||||
extraOffset = 0,
|
||||
fixed = false;
|
||||
|
||||
function init(selector) {
|
||||
$fixedItem = $(selector || '.submit-row');
|
||||
if (!$fixedItem.length)
|
||||
return;
|
||||
|
||||
$fixedItemParent = $fixedItem.parents('form');
|
||||
itemOffset = $fixedItem.offset();
|
||||
$win = $(window);
|
||||
window.onscroll = onScroll;
|
||||
window.onresize = onScroll;
|
||||
onScroll();
|
||||
|
||||
setInterval(function () {
|
||||
if (didScroll) {
|
||||
didScroll = false;
|
||||
}
|
||||
}, 200);
|
||||
}
|
||||
|
||||
function onScroll() {
|
||||
didScroll = true;
|
||||
|
||||
var itemHeight = $fixedItem.height(),
|
||||
scrollTop = $win.scrollTop();
|
||||
|
||||
if (scrollTop + $win.height() - itemHeight - extraOffset < itemOffset.top) {
|
||||
if (!fixed) {
|
||||
$fixedItem.addClass('fixed');
|
||||
$fixedItemParent.addClass('fixed').css('padding-bottom', itemHeight + 'px');
|
||||
fixed = true;
|
||||
}
|
||||
} else {
|
||||
if (fixed) {
|
||||
$fixedItem.removeClass('fixed');
|
||||
$fixedItemParent.removeClass('fixed').css('padding-bottom', '');
|
||||
fixed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
init: init
|
||||
};
|
||||
}();
|
||||
|
||||
/**
|
||||
* Avoids double-submit issues in the change_form.
|
||||
*/
|
||||
$.fn.suitFormDebounce = function () {
|
||||
var $form = $(this),
|
||||
$saveButtons = $form.find('.submit-row button, .submit-row input[type=button], .submit-row input[type=submit]'),
|
||||
submitting = false;
|
||||
|
||||
$form.submit(function () {
|
||||
if (submitting) {
|
||||
return false;
|
||||
}
|
||||
|
||||
submitting = true;
|
||||
$saveButtons.addClass('disabled');
|
||||
|
||||
setTimeout(function () {
|
||||
$saveButtons.removeClass('disabled');
|
||||
submitting = false;
|
||||
}, 5000);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Content tabs
|
||||
*/
|
||||
$.fn.suitFormTabs = function () {
|
||||
|
||||
var $tabs = $(this);
|
||||
var tabPrefix = $tabs.data('tab-prefix');
|
||||
if (!tabPrefix)
|
||||
return;
|
||||
|
||||
var $tabLinks = $tabs.find('a');
|
||||
|
||||
function tabContents($link) {
|
||||
return $('.' + tabPrefix + '-' + $link.attr('href').replace('#', ''));
|
||||
}
|
||||
|
||||
function activateTabs() {
|
||||
// Init tab by error, by url hash or init first tab
|
||||
if (window.location.hash) {
|
||||
var foundError;
|
||||
$tabLinks.each(function () {
|
||||
var $link = $(this);
|
||||
if (tabContents($link).find('.error, .errorlist').length != 0) {
|
||||
$link.addClass('has-error');
|
||||
$link.trigger('click');
|
||||
foundError = true;
|
||||
}
|
||||
});
|
||||
!foundError && $($tabs).find('a[href=\\' + window.location.hash + ']').click();
|
||||
} else {
|
||||
$tabLinks.first().trigger('click');
|
||||
}
|
||||
}
|
||||
|
||||
$tabLinks.click(function () {
|
||||
var $link = $(this),
|
||||
showEvent = $.Event('shown.suit.tab', {
|
||||
relatedTarget: $link,
|
||||
tab: $link.attr('href').replace('#', '')
|
||||
});
|
||||
$link.parent().parent().find('.active').removeClass('active');
|
||||
$link.addClass('active');
|
||||
$('.' + tabPrefix).removeClass('show').addClass('hidden-xs-up');
|
||||
tabContents($link).removeClass('hidden-xs-up').addClass('show');
|
||||
$link.trigger(showEvent);
|
||||
});
|
||||
|
||||
activateTabs();
|
||||
};
|
||||
|
||||
/* Characters count for CharacterCountTextarea */
|
||||
$.fn.suitCharactersCount = function () {
|
||||
var $elements = $(this);
|
||||
|
||||
if (!$elements.length)
|
||||
return;
|
||||
|
||||
$elements.each(function () {
|
||||
var $el = $(this),
|
||||
$countEl = $('<div class="suit-char-count"></div>');
|
||||
$el.after($countEl);
|
||||
$el.on('keyup', function (e) {
|
||||
updateCount($(e.currentTarget));
|
||||
});
|
||||
updateCount($el);
|
||||
});
|
||||
|
||||
function updateCount($el) {
|
||||
var maxCount = $el.data('suit-maxcount'),
|
||||
twitterCount = $el.data('suit-twitter-count'),
|
||||
value = $el.val(),
|
||||
len = twitterCount ? getTweetLength(value) : value.length,
|
||||
count = maxCount ? maxCount - len : len;
|
||||
if (count < 0)
|
||||
count = '<span class="text-danger">' + count + '</span>';
|
||||
|
||||
$el.next().first().html(count);
|
||||
}
|
||||
|
||||
function getTweetLength(input) {
|
||||
var tmp = "";
|
||||
for (var i = 0; i < 23; i++) {
|
||||
tmp += "o"
|
||||
}
|
||||
return input.replace(/(http:\/\/[\S]*)/g, tmp).length;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Search filters - submit only changed fields
|
||||
*/
|
||||
$.fn.suitSearchFilters = function () {
|
||||
$(this).change(function () {
|
||||
var $field = $(this);
|
||||
var $option = $field.find('option:selected');
|
||||
var select_name = $option.data('name');
|
||||
if (select_name) {
|
||||
$field.attr('name', select_name);
|
||||
} else {
|
||||
$field.removeAttr('name');
|
||||
}
|
||||
// Handle additional values for date filters
|
||||
var additional = $option.data('additional');
|
||||
console.log($field, additional)
|
||||
if (additional) {
|
||||
var hiddenId = $field.data('name') + '_add';
|
||||
var $hidden = $('#' + hiddenId);
|
||||
if (!$hidden.length) {
|
||||
$hidden = $('<input/>').attr('type', 'hidden').attr('id', hiddenId);
|
||||
$field.after($hidden);
|
||||
}
|
||||
additional = additional.split('=');
|
||||
$hidden.attr('name', additional[0]).val(additional[1])
|
||||
}
|
||||
});
|
||||
$(this).trigger('change');
|
||||
};
|
||||
|
||||
|
||||
})(typeof django !== 'undefined' ? django.jQuery : undefined);
|
|
@ -1,183 +0,0 @@
|
|||
/**
|
||||
* List sortables
|
||||
*/
|
||||
(function ($) {
|
||||
$.fn.suit_list_sortable = function () {
|
||||
var $inputs = $(this);
|
||||
if (!$inputs.length)
|
||||
return;
|
||||
|
||||
// Detect if this is normal or mptt table
|
||||
var mptt_table = $inputs.first().closest('table').hasClass('table-mptt');
|
||||
|
||||
function performMove($arrow, $row) {
|
||||
var $next, $prev;
|
||||
|
||||
$row.closest('table').find('tr.selected').removeClass('selected');
|
||||
if (mptt_table) {
|
||||
function getPadding($tr) {
|
||||
return parseInt($tr.find('th:first').css('padding-left'));
|
||||
}
|
||||
|
||||
function findWithChildren($tr) {
|
||||
var padding = getPadding($tr);
|
||||
return $tr.nextUntil(function () {
|
||||
return getPadding($(this)) <= padding
|
||||
}).andSelf();
|
||||
}
|
||||
|
||||
var padding = getPadding($row);
|
||||
var $rows_to_move = findWithChildren($row);
|
||||
if ($arrow.data('dir') === 'down') {
|
||||
$next = $rows_to_move.last().next();
|
||||
if ($next.length && getPadding($next) === padding) {
|
||||
var $after = findWithChildren($next).last();
|
||||
if ($after.length) {
|
||||
$rows_to_move.insertAfter($after).addClass('selected');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$prev = $row.prevUntil(function () {
|
||||
return getPadding($(this)) <= padding
|
||||
}).andSelf().first().prev();
|
||||
if ($prev.length && getPadding($prev) === padding) {
|
||||
$rows_to_move.insertBefore($prev).addClass('selected')
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ($arrow.data('dir') === 'down') {
|
||||
$next = $row.next();
|
||||
if ($next.is(':visible') && $next.length) {
|
||||
$row.insertAfter($next).addClass('selected')
|
||||
}
|
||||
} else {
|
||||
$prev = $row.prev();
|
||||
if ($prev.is(':visible') && $prev.length) {
|
||||
$row.insertBefore($prev).addClass('selected')
|
||||
}
|
||||
}
|
||||
}
|
||||
markLastInline($row.parent());
|
||||
}
|
||||
|
||||
function onArrowClick(e) {
|
||||
var $sortable = $(this);
|
||||
var $row = $sortable.closest(
|
||||
$sortable.hasClass('sortable-stacked') ? 'div.inline-related' : 'tr'
|
||||
);
|
||||
performMove($sortable, $row);
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
function createLink(text, direction, on_click_func, is_stacked) {
|
||||
return $('<a/>').attr('href', '#')
|
||||
.addClass('sortable sortable-' + direction +
|
||||
(is_stacked ? ' sortable-stacked' : ''))
|
||||
.attr('data-dir', direction).html(text)
|
||||
.on('click', on_click_func);
|
||||
}
|
||||
|
||||
function markLastInline($rowParent) {
|
||||
$rowParent.find(' > .last-sortable').removeClass('last-sortable');
|
||||
$rowParent.find('tr.form-row:visible:last').addClass('last-sortable');
|
||||
}
|
||||
|
||||
var $lastSortable;
|
||||
$inputs.each(function () {
|
||||
var $inline_sortable = $('<div class="inline-sortable"/>'),
|
||||
icon = '<span class="fa fa-lg fa-arrow-up"></span>',
|
||||
$sortable = $(this),
|
||||
is_stacked = $sortable.hasClass('suit-sortable-stacked');
|
||||
|
||||
var $up_link = createLink(icon, 'up', onArrowClick, is_stacked),
|
||||
$down_link = createLink(icon.replace('-up', '-down'), 'down', onArrowClick, is_stacked);
|
||||
|
||||
if (is_stacked) {
|
||||
var $sortable_row = $sortable.closest('div.form-group'),
|
||||
$stacked_block = $sortable.closest('div.inline-related'),
|
||||
$links_span = $('<span/>').attr('class', 'stacked-inline-sortable');
|
||||
|
||||
// Add arrows to header h3, move order input and remove order field row
|
||||
$links_span.append($up_link).append($down_link);
|
||||
$links_span.insertAfter($stacked_block.find('.inline_label'));
|
||||
$stacked_block.append($sortable);
|
||||
$sortable_row.remove();
|
||||
} else {
|
||||
$sortable.parent().append($inline_sortable);
|
||||
$inline_sortable.append($up_link);
|
||||
$inline_sortable.append($down_link);
|
||||
$lastSortable = $sortable;
|
||||
}
|
||||
});
|
||||
|
||||
$lastSortable && markLastInline($lastSortable.closest('.form-row').parent());
|
||||
|
||||
// Filters out unchanged checkboxes, selects and sortable field itself
|
||||
function filter_unchanged(i, input) {
|
||||
if (input.type == 'checkbox') {
|
||||
if (input.defaultChecked == input.checked) {
|
||||
return false;
|
||||
}
|
||||
} else if (input.type == 'select-one' || input.type == 'select-multiple') {
|
||||
var options = input.options, option;
|
||||
for (var j = 0; j < options.length; j++) {
|
||||
option = options[j];
|
||||
if (option.selected && option.selected == option.defaultSelected) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else if ($(input).hasClass('suit-sortable')) {
|
||||
if (input.defaultValue == input.value && input.value == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Update input count right before submit
|
||||
if ($inputs && $inputs.length) {
|
||||
var $last_input = $inputs.last();
|
||||
var selector = $(this).selector;
|
||||
$($last_input[0].form).submit(function (e) {
|
||||
var i = 0, value;
|
||||
// e.preventDefault();
|
||||
$(selector).each(function () {
|
||||
var $input = $(this);
|
||||
var fieldset_id = $input.attr('name').split(/-\d+-/)[0];
|
||||
// Check if any of new dynamic block values has been added
|
||||
var $set_block = $input.closest('.dynamic-' + fieldset_id);
|
||||
var $changed_fields = $set_block.find(":input[type!='hidden']:not(.suit-sortable)").filter(
|
||||
function () {
|
||||
return $(this).val() != "";
|
||||
}).filter(filter_unchanged);
|
||||
// console.log($changed_fields.length, $changed_fields);
|
||||
var is_changelist = !$set_block.length;
|
||||
if (is_changelist
|
||||
|| $set_block.hasClass('has_original')
|
||||
|| $changed_fields.serializeArray().length
|
||||
// Since jQuery serialize() doesn't include type=file do additional check
|
||||
|| $changed_fields.find(":input[type='file']").addBack().length) {
|
||||
value = i++;
|
||||
$input.val(value);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Suit.after_inline.register('bind_sortable_arrows', function (prefix, row) {
|
||||
$(row).find('.suit-sortable').on('click', onArrowClick);
|
||||
markLastInline($(row).parent());
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
$(function () {
|
||||
$('.suit-sortable').suit_list_sortable();
|
||||
});
|
||||
|
||||
}(django.jQuery));
|
||||
|
||||
// Call Suit.after_inline
|
||||
django.jQuery(document).on('formset:added', function (e, row, prefix) {
|
||||
Suit.after_inline.run(prefix, row);
|
||||
});
|
|
@ -0,0 +1,7 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<b>TODO: Acerca</b>
|
||||
|
||||
{% endblock %}
|
|
@ -1,57 +1,26 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<title>MauFlix</title>
|
||||
|
||||
{% load static %}
|
||||
<link rel="shortcut icon" href="{% static 'img/favicon.png' %}">
|
||||
<link rel="stylesheet" href="{% static 'css/bulma.min.css' %}" type="text/css">
|
||||
<link rel="stylesheet" href="{% static 'css/main.css' %}" type="text/css">
|
||||
<script type="text/javascript" src="{% static 'js/jquery-3.4.1.min.js' %}" ></script>
|
||||
<script type="text/javascript" src="{% static 'js/main.js' %}" ></script>
|
||||
{% block media %}{% endblock %}
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
});
|
||||
</script>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>MauFlix</title>
|
||||
{% load static %}
|
||||
<link rel="shortcut icon" href="{% static 'img/favicon.png' %}">
|
||||
<link rel="stylesheet" href="{% static 'css/bulma.min.css' %}">
|
||||
<link rel="stylesheet" href="{% static 'css/bulma.darkly.min.css' %}">
|
||||
<link rel="stylesheet" href="{% static 'css/main.css' %}">
|
||||
<script type="text/javascript" src="{% static 'js/main.js' %}"></script>
|
||||
</head>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<section class="hero is-light">
|
||||
<div class="hero-body">
|
||||
<div class="container">
|
||||
<h2 class="title"> MauFlix </h1>
|
||||
<p class="subtitle">
|
||||
Otras plataformas tienen todas las películas, excepto las que nos gustan :)
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div id="movies">
|
||||
{% block content %}{% endblock %}
|
||||
<section class="hero is-small is-info">
|
||||
<div class="hero-body has-text-centered">
|
||||
<p>Otras plataformas tienen todas las películas, excepto las que nos gustan :)</p>
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
<div class="content has-text-centered">
|
||||
<p>
|
||||
Site develop thanks to:
|
||||
<a href="https://python.org" target='_blank'>Python</a>,
|
||||
<a href="https://djangoproject.com/" target='_blank'>Django</a>,
|
||||
<a href="https://bulma.io/" target='_blank'>Bulma</a>.
|
||||
The website content is licensed <a href="http://creativecommons.org/licenses/by-nc-sa/4.0/" target='_blank'>CC BY NC SA 4.0</a>.
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
</section>
|
||||
{% include 'nav.html' %}
|
||||
<section id="main">
|
||||
{% block content %}{% endblock %}
|
||||
</section>
|
||||
{% include 'footer.html' %}
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<b>TODO: Reporta un problema</b>
|
||||
|
||||
{% endblock %}
|
|
@ -0,0 +1,19 @@
|
|||
<footer class="footer">
|
||||
<div class="content">
|
||||
<p><b>BCH</b>: <code>qztd3l00xle5tffdqvh2snvadkuau2ml0uqm4n875d</code></p>
|
||||
<p><b>BTC</b>: <code>3FhiXcXmAesmQzrNEngjHFnvaJRhU1AGWV</code></p>
|
||||
<p><b>LTC</b>: <code>MBcgQ3LQJA4W2wsXknTdm2fxRSysLaBJHS</code></p>
|
||||
<p><b>ETH</b>: <code>0x61a4f614a30ff686445751ed8328b82b77ecfc69</code></p>
|
||||
</div>
|
||||
<div class="content has-text-centered">
|
||||
<p>Te recomendamos <a href="https://www.videolan.org/vlc/" target="_blank">VLC</a> para ver tus películas.</p>
|
||||
</div>
|
||||
<div class="content has-text-centered">
|
||||
<p>
|
||||
Sitio desarrollado con
|
||||
<a href="https://python.org" target='_blank'>Python</a>,
|
||||
<a href="https://djangoproject.com/" target='_blank'>Django</a> y
|
||||
<a href="https://bulma.io/" target='_blank'>Bulma</a>.
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
|
@ -1,31 +1,12 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<p class="subtitle">
|
||||
Te recomendamos usar <a href="https://www.videolan.org/vlc/" target="_blank">VLC</a>
|
||||
para ver tus <a href="/movies">películas</a>.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<p class="">
|
||||
<b>BCH</b>: <code>qztd3l00xle5tffdqvh2snvadkuau2ml0uqm4n875d</code>
|
||||
</p>
|
||||
<p class="">
|
||||
<b>BTC</b>: <code>3FhiXcXmAesmQzrNEngjHFnvaJRhU1AGWV</code>
|
||||
</p>
|
||||
<p class="">
|
||||
<b>LTC</b>: <code>MBcgQ3LQJA4W2wsXknTdm2fxRSysLaBJHS</code>
|
||||
</p>
|
||||
<p class="">
|
||||
<b>ETH</b>: <code>0x61a4f614a30ff686445751ed8328b82b77ecfc69</code>
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{% for section, content in sections.items %}
|
||||
{% if section != "genders"%}
|
||||
{% include 'section.html' with section=section content=content %}
|
||||
{% else %}
|
||||
{% for gender, val in content.items %}
|
||||
{% include 'section.html' with section=gender content=val %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<script type='text/javascript' charset='utf-8'>
|
||||
|
||||
webix.ready(function(){
|
||||
webix.ui(ui_main)
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
|
@ -0,0 +1,43 @@
|
|||
<div class="hero-body movie-body">
|
||||
{% if request.get_full_path == "/" %}
|
||||
<div class="stats">
|
||||
<p class="stars">{{ movie.stars_icons }}</p>
|
||||
<p><i class="gg-time"></i>{{ movie.duration_formatted }}</p>
|
||||
<p><i class="gg-software-download"></i>{{ movie.count_formatted }}</p>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="about">
|
||||
<div class="columns is-desktop">
|
||||
<div class="column">
|
||||
<h2 class="subtitle">Cartel</h2>
|
||||
<figure>
|
||||
<img src="{{ movie.cartel }}">
|
||||
</figure>
|
||||
</div>
|
||||
<div class="column">
|
||||
<h2 class="subtitle">Ficha técnica</h2>
|
||||
<table class="table infobox">
|
||||
<tbody>
|
||||
<tr><td>Título original</td><td>{{ movie.original_name }}<td></tr>
|
||||
<tr><td>Año</td><td>{{ movie.year }}<td></tr>
|
||||
<tr><td>País</td><td>{{ movie.countries }}<td></tr>
|
||||
<tr><td>Duración</td><td>{{ movie.duration }} min<td></tr>
|
||||
<tr><td>Dirección</td><td>{{ movie.directors }}<td></tr>
|
||||
<tr><td>Reparto</td><td>{{ movie.actors }}<td></tr>
|
||||
<tr><td>Género</td><td>{{ movie.genders }}<td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{% if movie.wiki.summary %}
|
||||
<h2 class="subtitle">Sinopsis de <a href="{{ movie.wiki.url }}" target="_blank">Wikipedia</a></h2>
|
||||
{{ movie.wiki.summary | safe }}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if user.is_superuser %}
|
||||
<video controls>
|
||||
<source src="{{ movie.file_name }}" type="video/mp4">
|
||||
</video>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
|
@ -0,0 +1,12 @@
|
|||
<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>
|
|
@ -0,0 +1,10 @@
|
|||
<div class="hero-head movie-head">
|
||||
<p class="title">{{ movie.name }}</p>
|
||||
{% if request.get_full_path != "/" %}
|
||||
<p class="stats">
|
||||
<span class="stars">{{ movie.stars_icons }}</span>
|
||||
<span><i class="gg-time"></i>{{ movie.duration_formatted }}</span>
|
||||
<span><i class="gg-software-download"></i>{{ movie.count_formatted }}</span>
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
|
@ -0,0 +1,5 @@
|
|||
<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>
|
|
@ -0,0 +1,4 @@
|
|||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
{% include 'info.html' with movie=movie %}
|
||||
{% endblock %}
|
|
@ -1,87 +1,6 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<BR>
|
||||
|
||||
|
||||
<!-- Main container -->
|
||||
<nav class="level">
|
||||
<!-- Left side -->
|
||||
<div class="level-left">
|
||||
<div class="level-item">
|
||||
<p class="subtitle is-6">
|
||||
Mostrando <strong>{{count}}</strong> películas
|
||||
</p>
|
||||
</div>
|
||||
<div class="level-item">
|
||||
<div class="field has-addons">
|
||||
<p class="control">
|
||||
<input class="input" id='search' type="text" placeholder="Buscar por nombre">
|
||||
</p>
|
||||
<p class="control">
|
||||
<button class="button is-info is-light" onclick='search_movie();'>Buscar</button>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="level-item">
|
||||
<div class="select is-info">
|
||||
<select id='directors' onChange='director_change()'>
|
||||
<option>Por director</option>
|
||||
{% for director in directors %}
|
||||
{% ifequal selected_director director %}
|
||||
<option selected>{{director}}</option>
|
||||
{% else %}
|
||||
<option>{{director}}</option>
|
||||
{% endifequal %}
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Right side -->
|
||||
<div class="level-right">
|
||||
<p class="level-item">
|
||||
{% if args %}
|
||||
<button class="button is-info is-light"><a href="/movies/">Ultimas</a></button>
|
||||
{% else %}
|
||||
<button class="button is-info is-light"><a href="/movies/all">Ver Todas</a></button>
|
||||
{% endif %}
|
||||
</p>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
|
||||
{% for row in movies %}
|
||||
<div class="columns is-desktop is-variable is-1">
|
||||
{% for cell in row %}
|
||||
<div class="column" style="padding: 0.5rem;">
|
||||
<article class="media has-background-light custom-article">
|
||||
<figure class="media-left" style="padding-top: 0.75rem;">
|
||||
<img src='{{ cell.image }}' height='150' width='100'>
|
||||
</figure>
|
||||
<div class="media-content">
|
||||
<div class="content">
|
||||
<p>
|
||||
<strong><a class='downmovie' href='{{ cell.url }}' id={{ cell.id }}>{{ cell.name }}</a></strong>
|
||||
<BR>
|
||||
({{ cell.original_name }})
|
||||
</p>
|
||||
<p>
|
||||
<strong>Director</strong>: {{ cell.director }} <br>
|
||||
<strong>País</strong>: {{ cell.country }} <br>
|
||||
<strong>Año</strong>: {{ cell.year }}, <strong>Duración</strong>: {{ cell.duration }} <br>
|
||||
<strong>Descargas</strong>: <span id='down{{cell.id}}'>{{ cell.count }}</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% for section, content in sections.items %}
|
||||
{% include 'section.html' with section=section content=content %}
|
||||
{% endfor %}
|
||||
|
||||
<BR>
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
<nav id="nav" class="navbar" role="navigation" aria-label="main navigation">
|
||||
{% load static %}
|
||||
<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 force-display">
|
||||
<div class="navbar-start">
|
||||
{% 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>
|
||||
{% endif %}
|
||||
<div class="navbar-item has-dropdown is-hoverable">
|
||||
<a class="navbar-link">Más</a>
|
||||
<div class="navbar-dropdown">
|
||||
<a class="navbar-item" href="{% url 'about' %}" >Acerca</a>
|
||||
<hr class="navbar-divider">
|
||||
<a class="navbar-item" href="{% url 'bugs' %}">Reporta un problema</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="navbar-end">
|
||||
<div class="navbar-item">
|
||||
<div class="buttons">
|
||||
<a class="button is-primary" href="{% url 'admin:index' %}">Ingresa</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
|
@ -0,0 +1,7 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<b>TODO: Búsqueda</b>
|
||||
|
||||
{% endblock %}
|
|
@ -0,0 +1,22 @@
|
|||
<section class="hero">
|
||||
<div class="hero-body hero-cartels">
|
||||
{% if request.get_full_path == "/" %}
|
||||
<p class="title"><a href="movies/{{ section }}">{{ section }}<span class="arrows"/></a></p>
|
||||
{% else %}
|
||||
<p class="title">{{ section }}</p>
|
||||
{% endif %}
|
||||
<div class="cartels">
|
||||
{% for movie in content %}
|
||||
<div class="cartel">
|
||||
<input type="checkbox" class="toggle">
|
||||
<div class="info">
|
||||
{% include 'info.html' with movie=movie %}
|
||||
</div>
|
||||
<figure class="image is-2by3">
|
||||
<img src="{{ movie.cartel }}">
|
||||
</figure>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
Loading…
Reference in New Issue