diff --git a/Django/README.md b/Django/README.md
deleted file mode 100644
index b2c76d2..0000000
--- a/Django/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Fuente usada
-
-https://docs.djangoproject.com/en/5.0/intro/tutorial01/
\ No newline at end of file
diff --git a/Django/mysite/polls/admin.py b/Django/mysite/polls/admin.py
deleted file mode 100644
index a60697e..0000000
--- a/Django/mysite/polls/admin.py
+++ /dev/null
@@ -1,22 +0,0 @@
-from django.contrib import admin
-
-from .models import Choice, Question
-
-
-class ChoiceInline(admin.TabularInline):
- model = Choice
- extra = 3
-
-
-class QuestionAdmin(admin.ModelAdmin):
- fieldsets = [
- (None, {"fields": ["question_text"]}),
- ("Date information", {"fields": ["pub_date"], "classes": ["collapse"]}),
- ]
- inlines = [ChoiceInline]
- list_display = ["question_text", "pub_date", "was_published_recently"]
- list_filter = ["pub_date"]
- search_fields = ["question_text"]
-
-
-admin.site.register(Question, QuestionAdmin)
\ No newline at end of file
diff --git a/Django/mysite/polls/migrations/0001_initial.py b/Django/mysite/polls/migrations/0001_initial.py
deleted file mode 100644
index 370ace2..0000000
--- a/Django/mysite/polls/migrations/0001_initial.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# Generated by Django 5.0.7 on 2024-07-18 08:36
-
-import django.db.models.deletion
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- initial = True
-
- dependencies = [
- ]
-
- operations = [
- migrations.CreateModel(
- name='Question',
- fields=[
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('question_text', models.CharField(max_length=200)),
- ('pub_date', models.DateTimeField(verbose_name='date published')),
- ],
- ),
- migrations.CreateModel(
- name='Choice',
- fields=[
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('choice_text', models.CharField(max_length=200)),
- ('votes', models.IntegerField(default=0)),
- ('question', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='polls.question')),
- ],
- ),
- ]
diff --git a/Django/mysite/polls/models.py b/Django/mysite/polls/models.py
deleted file mode 100644
index bc46f33..0000000
--- a/Django/mysite/polls/models.py
+++ /dev/null
@@ -1,34 +0,0 @@
-import datetime
-from django.db import models
-from django.utils import timezone
-from django.contrib import admin
-
-
-# Create your models here.
-
-class Question(models.Model):
- question_text = models.CharField(max_length=200)
- pub_date = models.DateTimeField("date published")
-
- def __str__(self):
- return self.question_text
-
- @admin.display(
- boolean=True,
- ordering="pub_date",
- description="Published recently?",
- )
-
-
-
- def was_published_recently(self):
- now = timezone.now()
- return now - datetime.timedelta(days=1) <= self.pub_date <= now
-
-class Choice(models.Model):
- question = models.ForeignKey(Question, on_delete=models.CASCADE)
- choice_text = models.CharField(max_length=200)
- votes = models.IntegerField(default=0)
-
- def __str__(self):
- return self.choice_text
diff --git a/Django/mysite/polls/static/polls/images/background.jpeg b/Django/mysite/polls/static/polls/images/background.jpeg
deleted file mode 100644
index a500a1c..0000000
Binary files a/Django/mysite/polls/static/polls/images/background.jpeg and /dev/null differ
diff --git a/Django/mysite/polls/static/polls/style.css b/Django/mysite/polls/static/polls/style.css
deleted file mode 100644
index 7693ee6..0000000
--- a/Django/mysite/polls/static/polls/style.css
+++ /dev/null
@@ -1,8 +0,0 @@
-li a {
- color: green;
-}
-
-body {
- background: white url("images/background.jpeg") no-repeat;
- background-size: 50% 50%;
-}
\ No newline at end of file
diff --git a/Django/mysite/polls/templates/polls/detail.html b/Django/mysite/polls/templates/polls/detail.html
deleted file mode 100644
index 55fa300..0000000
--- a/Django/mysite/polls/templates/polls/detail.html
+++ /dev/null
@@ -1,12 +0,0 @@
-
\ No newline at end of file
diff --git a/Django/mysite/polls/templates/polls/index.html b/Django/mysite/polls/templates/polls/index.html
deleted file mode 100644
index 04410ae..0000000
--- a/Django/mysite/polls/templates/polls/index.html
+++ /dev/null
@@ -1,13 +0,0 @@
-{% load static %}
-
-
-
-{% if latest_question_list %}
-
-{% else %}
- No polls are available.
-{% endif %}
\ No newline at end of file
diff --git a/Django/mysite/polls/templates/polls/results.html b/Django/mysite/polls/templates/polls/results.html
deleted file mode 100644
index 33b67b2..0000000
--- a/Django/mysite/polls/templates/polls/results.html
+++ /dev/null
@@ -1,9 +0,0 @@
-{{ question.question_text }}
-
-
-{% for choice in question.choice_set.all %}
- {{ choice.choice_text }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}
-{% endfor %}
-
-
-Vote again?
\ No newline at end of file
diff --git a/Django/mysite/polls/tests.py b/Django/mysite/polls/tests.py
deleted file mode 100644
index 01c97d0..0000000
--- a/Django/mysite/polls/tests.py
+++ /dev/null
@@ -1,102 +0,0 @@
-import datetime
-
-from django.test import TestCase
-from django.utils import timezone
-from django.urls import reverse
-
-from .models import Question
-
-
-def create_question(question_text, days):
- """
- Create a question with the given `question_text` and published the
- given number of `days` offset to now (negative for questions published
- in the past, positive for questions that have yet to be published).
- """
- time = timezone.now() + datetime.timedelta(days=days)
- return Question.objects.create(question_text=question_text, pub_date=time)
-
-class QuestionModelTests(TestCase):
- def test_was_published_recently_with_future_question(self):
- """
- was_published_recently() returns False for questions whose pub_date
- is in the future.
- """
- time = timezone.now() + datetime.timedelta(days=30)
- future_question = Question(pub_date=time)
- self.assertIs(future_question.was_published_recently(), False)
-
- def test_was_published_recently_with_old_question(self):
- """
- was_published_recently() returns False for questions whose pub_date
- is older than 1 day.
- """
- time = timezone.now() - datetime.timedelta(days=1, seconds=1)
- old_question = Question(pub_date=time)
- self.assertIs(old_question.was_published_recently(), False)
-
-
- def test_was_published_recently_with_recent_question(self):
- """
- was_published_recently() returns True for questions whose pub_date
- is within the last day.
- """
- time = timezone.now() - datetime.timedelta(hours=23, minutes=59, seconds=59)
- recent_question = Question(pub_date=time)
- self.assertIs(recent_question.was_published_recently(), True)
-
-class QuestionIndexViewTests(TestCase):
-
- def test_no_questions(self):
- """
- If no questions exist, an appropriate message is displayed.
- """
- response = self.client.get(reverse("polls:index"))
- self.assertEqual(response.status_code, 200)
- self.assertContains(response, "No polls are available.")
- self.assertQuerySetEqual(response.context["latest_question_list"], [])
-
- def test_future_question(self):
- """
- The detail view of a question with a pub_date in the future
- returns a 404 not found.
- """
- future_question = create_question(question_text="Future question.", days=5)
- url = reverse("polls:detail", args=(future_question.id,))
- response = self.client.get(url)
- self.assertEqual(response.status_code, 404)
-
- def test_past_question(self):
- """
- The detail view of a question with a pub_date in the past
- displays the question's text.
- """
- past_question = create_question(question_text="Past Question.", days=-5)
- url = reverse("polls:detail", args=(past_question.id,))
- response = self.client.get(url)
- self.assertContains(response, past_question.question_text)
-
- def test_future_question_and_past_question(self):
- """
- Even if both past and future questions exist, only past questions
- are displayed.
- """
- question = create_question(question_text="Past question.", days=-30)
- create_question(question_text="Future question.", days=30)
- response = self.client.get(reverse("polls:index"))
- self.assertQuerySetEqual(
- response.context["latest_question_list"],
- [question],
- )
-
- def test_two_past_questions(self):
- """
- The questions index page may display multiple questions.
- """
- question1 = create_question(question_text="Past question 1.", days=-30)
- question2 = create_question(question_text="Past question 2.", days=-5)
- response = self.client.get(reverse("polls:index"))
- self.assertQuerySetEqual(
- response.context["latest_question_list"],
- [question2, question1],
- )
diff --git a/Django/mysite/polls/urls.py b/Django/mysite/polls/urls.py
deleted file mode 100644
index a2b6cc3..0000000
--- a/Django/mysite/polls/urls.py
+++ /dev/null
@@ -1,11 +0,0 @@
-from django.urls import path
-
-from . import views
-
-app_name = "polls"
-urlpatterns = [
- path("", views.IndexView.as_view(), name="index"),
- path("/", views.DetailView.as_view(), name="detail"),
- path("/results/", views.ResultsView.as_view(), name="results"),
- path("/vote/", views.vote, name="vote"),
-]
\ No newline at end of file
diff --git a/Django/mysite/polls/views.py b/Django/mysite/polls/views.py
deleted file mode 100644
index 3940542..0000000
--- a/Django/mysite/polls/views.py
+++ /dev/null
@@ -1,62 +0,0 @@
-from django.shortcuts import get_object_or_404, render
-from django.http import HttpResponse, HttpResponseRedirect
-from django.urls import reverse
-from django.db.models import F
-from django.views import generic
-from django.utils import timezone
-
-
-
-from .models import Choice, Question
-
-# Create your views here.
-
-
-class IndexView(generic.ListView):
- template_name = "polls/index.html"
- context_object_name = "latest_question_list"
-
- def get_queryset(self):
- """
- Return the last five published questions (not including those set to be
- published in the future).
- """
- return Question.objects.filter(pub_date__lte=timezone.now()).order_by("-pub_date")[
- :5
- ]
-
-class DetailView(generic.DetailView):
- model = Question
- template_name = "polls/detail.html"
-
- def get_queryset(self):
- """
- Excludes any questions that aren't published yet.
- """
- return Question.objects.filter(pub_date__lte=timezone.now())
-
-class ResultsView(generic.DetailView):
- model = Question
- template_name = "polls/results.html"
-
-def vote(request, question_id):
- question = get_object_or_404(Question, pk=question_id)
- try:
- selected_choice = question.choice_set.get(pk=request.POST["choice"])
- except (KeyError, Choice.DoesNotExist):
- # Redisplay the question voting form.
- return render(
- request,
- "polls/detail.html",
- {
- "question": question,
- "error_message": "You didn't select a choice.",
- },
- )
- else:
- selected_choice.votes = F("votes") + 1
- selected_choice.save()
- # Always return an HttpResponseRedirect after successfully dealing
- # with POST data. This prevents data from being posted twice if a
- # user hits the Back button.
- return HttpResponseRedirect(reverse("polls:results", args=(question.id,)))
\ No newline at end of file
diff --git a/Django/mysite/templates/admin/base_site.html b/Django/mysite/templates/admin/base_site.html
deleted file mode 100644
index 6aa80af..0000000
--- a/Django/mysite/templates/admin/base_site.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{% extends "admin/base.html" %}
-
-{% block title %}{% if subtitle %}{{ subtitle }} | {% endif %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% endblock %}
-
-{% block branding %}
-
-{% if user.is_anonymous %}
- {% include "admin/color_theme_toggle.html" %}
-{% endif %}
-{% endblock %}
-
-{% block nav-global %}{% endblock %}
\ No newline at end of file
diff --git a/Libros/Pipfile b/Libros/Pipfile
new file mode 100644
index 0000000..f5eb3db
--- /dev/null
+++ b/Libros/Pipfile
@@ -0,0 +1,16 @@
+[[source]]
+url = "https://pypi.org/simple"
+verify_ssl = true
+name = "pypi"
+
+[packages]
+django = "*"
+djangorestframework = "*"
+epub-meta = "*"
+django-db = "*"
+pillow = "*"
+
+[dev-packages]
+
+[requires]
+python_version = "3.10"
diff --git a/Libros/Pipfile.lock b/Libros/Pipfile.lock
new file mode 100644
index 0000000..1944333
--- /dev/null
+++ b/Libros/Pipfile.lock
@@ -0,0 +1,172 @@
+{
+ "_meta": {
+ "hash": {
+ "sha256": "ef4cc3e12936cd221526bb3ceae7ac1b1b7593040426b99e3ef1b167fe85abf5"
+ },
+ "pipfile-spec": 6,
+ "requires": {
+ "python_version": "3.10"
+ },
+ "sources": [
+ {
+ "name": "pypi",
+ "url": "https://pypi.org/simple",
+ "verify_ssl": true
+ }
+ ]
+ },
+ "default": {
+ "asgiref": {
+ "hashes": [
+ "sha256:3e1e3ecc849832fe52ccf2cb6686b7a55f82bb1d6aee72a58826471390335e47",
+ "sha256:c343bd80a0bec947a9860adb4c432ffa7db769836c64238fc34bdc3fec84d590"
+ ],
+ "markers": "python_version >= '3.8'",
+ "version": "==3.8.1"
+ },
+ "django": {
+ "hashes": [
+ "sha256:bd4505cae0b9bd642313e8fb71810893df5dc2ffcacaa67a33af2d5cd61888f2",
+ "sha256:f216510ace3de5de01329463a315a629f33480e893a9024fc93d8c32c22913da"
+ ],
+ "index": "pypi",
+ "markers": "python_version >= '3.10'",
+ "version": "==5.0.7"
+ },
+ "django-db": {
+ "hashes": [
+ "sha256:8639b6f78f04f34294cb465b308992a84297df41033519efd85b3a6b186b5296"
+ ],
+ "index": "pypi",
+ "version": "==0.0.7"
+ },
+ "djangorestframework": {
+ "hashes": [
+ "sha256:2b8871b062ba1aefc2de01f773875441a961fefbf79f5eed1e32b2f096944b20",
+ "sha256:36fe88cd2d6c6bec23dca9804bab2ba5517a8bb9d8f47ebc68981b56840107ad"
+ ],
+ "index": "pypi",
+ "markers": "python_version >= '3.8'",
+ "version": "==3.15.2"
+ },
+ "epub-meta": {
+ "hashes": [
+ "sha256:9d9c6afeaef796105a77d0aef33a1c943ccd91cccb2cb7716f59ad149819a4e9"
+ ],
+ "index": "pypi",
+ "version": "==0.0.7"
+ },
+ "pillow": {
+ "hashes": [
+ "sha256:02a2be69f9c9b8c1e97cf2713e789d4e398c751ecfd9967c18d0ce304efbf885",
+ "sha256:030abdbe43ee02e0de642aee345efa443740aa4d828bfe8e2eb11922ea6a21ea",
+ "sha256:06b2f7898047ae93fad74467ec3d28fe84f7831370e3c258afa533f81ef7f3df",
+ "sha256:0755ffd4a0c6f267cccbae2e9903d95477ca2f77c4fcf3a3a09570001856c8a5",
+ "sha256:0a9ec697746f268507404647e531e92889890a087e03681a3606d9b920fbee3c",
+ "sha256:0ae24a547e8b711ccaaf99c9ae3cd975470e1a30caa80a6aaee9a2f19c05701d",
+ "sha256:134ace6dc392116566980ee7436477d844520a26a4b1bd4053f6f47d096997fd",
+ "sha256:166c1cd4d24309b30d61f79f4a9114b7b2313d7450912277855ff5dfd7cd4a06",
+ "sha256:1b5dea9831a90e9d0721ec417a80d4cbd7022093ac38a568db2dd78363b00908",
+ "sha256:1d846aea995ad352d4bdcc847535bd56e0fd88d36829d2c90be880ef1ee4668a",
+ "sha256:1ef61f5dd14c300786318482456481463b9d6b91ebe5ef12f405afbba77ed0be",
+ "sha256:297e388da6e248c98bc4a02e018966af0c5f92dfacf5a5ca22fa01cb3179bca0",
+ "sha256:298478fe4f77a4408895605f3482b6cc6222c018b2ce565c2b6b9c354ac3229b",
+ "sha256:29dbdc4207642ea6aad70fbde1a9338753d33fb23ed6956e706936706f52dd80",
+ "sha256:2db98790afc70118bd0255c2eeb465e9767ecf1f3c25f9a1abb8ffc8cfd1fe0a",
+ "sha256:32cda9e3d601a52baccb2856b8ea1fc213c90b340c542dcef77140dfa3278a9e",
+ "sha256:37fb69d905be665f68f28a8bba3c6d3223c8efe1edf14cc4cfa06c241f8c81d9",
+ "sha256:416d3a5d0e8cfe4f27f574362435bc9bae57f679a7158e0096ad2beb427b8696",
+ "sha256:43efea75eb06b95d1631cb784aa40156177bf9dd5b4b03ff38979e048258bc6b",
+ "sha256:4b35b21b819ac1dbd1233317adeecd63495f6babf21b7b2512d244ff6c6ce309",
+ "sha256:4d9667937cfa347525b319ae34375c37b9ee6b525440f3ef48542fcf66f2731e",
+ "sha256:5161eef006d335e46895297f642341111945e2c1c899eb406882a6c61a4357ab",
+ "sha256:543f3dc61c18dafb755773efc89aae60d06b6596a63914107f75459cf984164d",
+ "sha256:551d3fd6e9dc15e4c1eb6fc4ba2b39c0c7933fa113b220057a34f4bb3268a060",
+ "sha256:59291fb29317122398786c2d44427bbd1a6d7ff54017075b22be9d21aa59bd8d",
+ "sha256:5b001114dd152cfd6b23befeb28d7aee43553e2402c9f159807bf55f33af8a8d",
+ "sha256:5b4815f2e65b30f5fbae9dfffa8636d992d49705723fe86a3661806e069352d4",
+ "sha256:5dc6761a6efc781e6a1544206f22c80c3af4c8cf461206d46a1e6006e4429ff3",
+ "sha256:5e84b6cc6a4a3d76c153a6b19270b3526a5a8ed6b09501d3af891daa2a9de7d6",
+ "sha256:6209bb41dc692ddfee4942517c19ee81b86c864b626dbfca272ec0f7cff5d9fb",
+ "sha256:673655af3eadf4df6b5457033f086e90299fdd7a47983a13827acf7459c15d94",
+ "sha256:6c762a5b0997f5659a5ef2266abc1d8851ad7749ad9a6a5506eb23d314e4f46b",
+ "sha256:7086cc1d5eebb91ad24ded9f58bec6c688e9f0ed7eb3dbbf1e4800280a896496",
+ "sha256:73664fe514b34c8f02452ffb73b7a92c6774e39a647087f83d67f010eb9a0cf0",
+ "sha256:76a911dfe51a36041f2e756b00f96ed84677cdeb75d25c767f296c1c1eda1319",
+ "sha256:780c072c2e11c9b2c7ca37f9a2ee8ba66f44367ac3e5c7832afcfe5104fd6d1b",
+ "sha256:7928ecbf1ece13956b95d9cbcfc77137652b02763ba384d9ab508099a2eca856",
+ "sha256:7970285ab628a3779aecc35823296a7869f889b8329c16ad5a71e4901a3dc4ef",
+ "sha256:7a8d4bade9952ea9a77d0c3e49cbd8b2890a399422258a77f357b9cc9be8d680",
+ "sha256:7c1ee6f42250df403c5f103cbd2768a28fe1a0ea1f0f03fe151c8741e1469c8b",
+ "sha256:7dfecdbad5c301d7b5bde160150b4db4c659cee2b69589705b6f8a0c509d9f42",
+ "sha256:812f7342b0eee081eaec84d91423d1b4650bb9828eb53d8511bcef8ce5aecf1e",
+ "sha256:866b6942a92f56300012f5fbac71f2d610312ee65e22f1aa2609e491284e5597",
+ "sha256:86dcb5a1eb778d8b25659d5e4341269e8590ad6b4e8b44d9f4b07f8d136c414a",
+ "sha256:87dd88ded2e6d74d31e1e0a99a726a6765cda32d00ba72dc37f0651f306daaa8",
+ "sha256:8bc1a764ed8c957a2e9cacf97c8b2b053b70307cf2996aafd70e91a082e70df3",
+ "sha256:8d4d5063501b6dd4024b8ac2f04962d661222d120381272deea52e3fc52d3736",
+ "sha256:8f0aef4ef59694b12cadee839e2ba6afeab89c0f39a3adc02ed51d109117b8da",
+ "sha256:930044bb7679ab003b14023138b50181899da3f25de50e9dbee23b61b4de2126",
+ "sha256:950be4d8ba92aca4b2bb0741285a46bfae3ca699ef913ec8416c1b78eadd64cd",
+ "sha256:961a7293b2457b405967af9c77dcaa43cc1a8cd50d23c532e62d48ab6cdd56f5",
+ "sha256:9b885f89040bb8c4a1573566bbb2f44f5c505ef6e74cec7ab9068c900047f04b",
+ "sha256:9f4727572e2918acaa9077c919cbbeb73bd2b3ebcfe033b72f858fc9fbef0026",
+ "sha256:a02364621fe369e06200d4a16558e056fe2805d3468350df3aef21e00d26214b",
+ "sha256:a985e028fc183bf12a77a8bbf36318db4238a3ded7fa9df1b9a133f1cb79f8fc",
+ "sha256:ac1452d2fbe4978c2eec89fb5a23b8387aba707ac72810d9490118817d9c0b46",
+ "sha256:b15e02e9bb4c21e39876698abf233c8c579127986f8207200bc8a8f6bb27acf2",
+ "sha256:b2724fdb354a868ddf9a880cb84d102da914e99119211ef7ecbdc613b8c96b3c",
+ "sha256:bbc527b519bd3aa9d7f429d152fea69f9ad37c95f0b02aebddff592688998abe",
+ "sha256:bcd5e41a859bf2e84fdc42f4edb7d9aba0a13d29a2abadccafad99de3feff984",
+ "sha256:bd2880a07482090a3bcb01f4265f1936a903d70bc740bfcb1fd4e8a2ffe5cf5a",
+ "sha256:bee197b30783295d2eb680b311af15a20a8b24024a19c3a26431ff83eb8d1f70",
+ "sha256:bf2342ac639c4cf38799a44950bbc2dfcb685f052b9e262f446482afaf4bffca",
+ "sha256:c76e5786951e72ed3686e122d14c5d7012f16c8303a674d18cdcd6d89557fc5b",
+ "sha256:cbed61494057c0f83b83eb3a310f0bf774b09513307c434d4366ed64f4128a91",
+ "sha256:cfdd747216947628af7b259d274771d84db2268ca062dd5faf373639d00113a3",
+ "sha256:d7480af14364494365e89d6fddc510a13e5a2c3584cb19ef65415ca57252fb84",
+ "sha256:dbc6ae66518ab3c5847659e9988c3b60dc94ffb48ef9168656e0019a93dbf8a1",
+ "sha256:dc3e2db6ba09ffd7d02ae9141cfa0ae23393ee7687248d46a7507b75d610f4f5",
+ "sha256:dfe91cb65544a1321e631e696759491ae04a2ea11d36715eca01ce07284738be",
+ "sha256:e4d49b85c4348ea0b31ea63bc75a9f3857869174e2bf17e7aba02945cd218e6f",
+ "sha256:e4db64794ccdf6cb83a59d73405f63adbe2a1887012e308828596100a0b2f6cc",
+ "sha256:e553cad5179a66ba15bb18b353a19020e73a7921296a7979c4a2b7f6a5cd57f9",
+ "sha256:e88d5e6ad0d026fba7bdab8c3f225a69f063f116462c49892b0149e21b6c0a0e",
+ "sha256:ecd85a8d3e79cd7158dec1c9e5808e821feea088e2f69a974db5edf84dc53141",
+ "sha256:f5b92f4d70791b4a67157321c4e8225d60b119c5cc9aee8ecf153aace4aad4ef",
+ "sha256:f5f0c3e969c8f12dd2bb7e0b15d5c468b51e5017e01e2e867335c81903046a22",
+ "sha256:f7baece4ce06bade126fb84b8af1c33439a76d8a6fd818970215e0560ca28c27",
+ "sha256:ff25afb18123cea58a591ea0244b92eb1e61a1fd497bf6d6384f09bc3262ec3e",
+ "sha256:ff337c552345e95702c5fde3158acb0625111017d0e5f24bf3acdb9cc16b90d1"
+ ],
+ "index": "pypi",
+ "markers": "python_version >= '3.8'",
+ "version": "==10.4.0"
+ },
+ "pymysql": {
+ "hashes": [
+ "sha256:4de15da4c61dc132f4fb9ab763063e693d521a80fd0e87943b9a453dd4c19d6c",
+ "sha256:e127611aaf2b417403c60bf4dc570124aeb4a57f5f37b8e95ae399a42f904cd0"
+ ],
+ "markers": "python_version >= '3.7'",
+ "version": "==1.1.1"
+ },
+ "sqlparse": {
+ "hashes": [
+ "sha256:773dcbf9a5ab44a090f3441e2180efe2560220203dc2f8c0b0fa141e18b505e4",
+ "sha256:bb6b4df465655ef332548e24f08e205afc81b9ab86cb1c45657a7ff173a3a00e"
+ ],
+ "markers": "python_version >= '3.8'",
+ "version": "==0.5.1"
+ },
+ "typing-extensions": {
+ "hashes": [
+ "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d",
+ "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"
+ ],
+ "markers": "python_version < '3.11'",
+ "version": "==4.12.2"
+ }
+ },
+ "develop": {}
+}
diff --git a/Libros/biblioteca/autores/auster.jpg b/Libros/biblioteca/autores/auster.jpg
new file mode 100644
index 0000000..6c22542
Binary files /dev/null and b/Libros/biblioteca/autores/auster.jpg differ
diff --git a/Libros/biblioteca/autores/daniel.jpg b/Libros/biblioteca/autores/daniel.jpg
new file mode 100644
index 0000000..d7775bd
Binary files /dev/null and b/Libros/biblioteca/autores/daniel.jpg differ
diff --git a/Django/mysite/mysite/__init__.py b/Libros/biblioteca/biblioteca/__init__.py
similarity index 100%
rename from Django/mysite/mysite/__init__.py
rename to Libros/biblioteca/biblioteca/__init__.py
diff --git a/Django/mysite/mysite/asgi.py b/Libros/biblioteca/biblioteca/asgi.py
similarity index 73%
rename from Django/mysite/mysite/asgi.py
rename to Libros/biblioteca/biblioteca/asgi.py
index cb29d22..6ee75a0 100644
--- a/Django/mysite/mysite/asgi.py
+++ b/Libros/biblioteca/biblioteca/asgi.py
@@ -1,5 +1,5 @@
"""
-ASGI config for mysite project.
+ASGI config for biblioteca project.
It exposes the ASGI callable as a module-level variable named ``application``.
@@ -11,6 +11,6 @@ import os
from django.core.asgi import get_asgi_application
-os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'biblioteca.settings')
application = get_asgi_application()
diff --git a/Django/mysite/mysite/settings.py b/Libros/biblioteca/biblioteca/settings.py
similarity index 90%
rename from Django/mysite/mysite/settings.py
rename to Libros/biblioteca/biblioteca/settings.py
index ba2a3dc..0c4d85f 100644
--- a/Django/mysite/mysite/settings.py
+++ b/Libros/biblioteca/biblioteca/settings.py
@@ -1,5 +1,5 @@
"""
-Django settings for mysite project.
+Django settings for biblioteca project.
Generated by 'django-admin startproject' using Django 5.0.7.
@@ -20,7 +20,7 @@ BASE_DIR = Path(__file__).resolve().parent.parent
# See https://docs.djangoproject.com/en/5.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
-SECRET_KEY = 'django-insecure-wussf@h6r5!#*1ko$6k!h9i2%sv-a3y)m6v6$ehn4_a0t0b01&'
+SECRET_KEY = 'django-insecure-q0bxrr=*ab*b8oa#=+-@_4cu-cp6)c3lz#+!c_%51$*!bnz%4!'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
@@ -31,13 +31,13 @@ ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
- "polls.apps.PollsConfig",
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
+ 'gestion',
]
MIDDLEWARE = [
@@ -50,12 +50,12 @@ MIDDLEWARE = [
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
-ROOT_URLCONF = 'mysite.urls'
+ROOT_URLCONF = 'biblioteca.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
- 'DIRS': [BASE_DIR / "templates"],
+ 'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
@@ -68,7 +68,7 @@ TEMPLATES = [
},
]
-WSGI_APPLICATION = 'mysite.wsgi.application'
+WSGI_APPLICATION = 'biblioteca.wsgi.application'
# Database
@@ -104,9 +104,9 @@ AUTH_PASSWORD_VALIDATORS = [
# Internationalization
# https://docs.djangoproject.com/en/5.0/topics/i18n/
-LANGUAGE_CODE = 'es-es'
+LANGUAGE_CODE = 'en-us'
-TIME_ZONE = 'Europe/Madrid'
+TIME_ZONE = 'UTC'
USE_I18N = True
diff --git a/Django/mysite/mysite/urls.py b/Libros/biblioteca/biblioteca/urls.py
similarity index 69%
rename from Django/mysite/mysite/urls.py
rename to Libros/biblioteca/biblioteca/urls.py
index a3df621..63da708 100644
--- a/Django/mysite/mysite/urls.py
+++ b/Libros/biblioteca/biblioteca/urls.py
@@ -1,5 +1,5 @@
"""
-URL configuration for mysite project.
+URL configuration for biblioteca project.
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/5.0/topics/http/urls/
@@ -16,8 +16,14 @@ Including another URLconf
"""
from django.contrib import admin
from django.urls import path, include
+from django.conf import settings
+from django.conf.urls.static import static
urlpatterns = [
- path("polls/", include("polls.urls")),
- path('admin/', admin.site.urls),
+ path('obreros/', admin.site.urls),
+ path('gestion/', include('gestion.urls')),
]
+
+
+if settings.DEBUG:
+ urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
diff --git a/Django/mysite/mysite/wsgi.py b/Libros/biblioteca/biblioteca/wsgi.py
similarity index 73%
rename from Django/mysite/mysite/wsgi.py
rename to Libros/biblioteca/biblioteca/wsgi.py
index 1925037..87168aa 100644
--- a/Django/mysite/mysite/wsgi.py
+++ b/Libros/biblioteca/biblioteca/wsgi.py
@@ -1,5 +1,5 @@
"""
-WSGI config for mysite project.
+WSGI config for biblioteca project.
It exposes the WSGI callable as a module-level variable named ``application``.
@@ -11,6 +11,6 @@ import os
from django.core.wsgi import get_wsgi_application
-os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'biblioteca.settings')
application = get_wsgi_application()
diff --git a/Django/mysite/db.sqlite3 b/Libros/biblioteca/db.sqlite3
similarity index 91%
rename from Django/mysite/db.sqlite3
rename to Libros/biblioteca/db.sqlite3
index f746306..4e6304f 100644
Binary files a/Django/mysite/db.sqlite3 and b/Libros/biblioteca/db.sqlite3 differ
diff --git a/Django/mysite/polls/__init__.py b/Libros/biblioteca/gestion/__init__.py
similarity index 100%
rename from Django/mysite/polls/__init__.py
rename to Libros/biblioteca/gestion/__init__.py
diff --git a/Libros/biblioteca/gestion/admin.py b/Libros/biblioteca/gestion/admin.py
new file mode 100644
index 0000000..027b055
--- /dev/null
+++ b/Libros/biblioteca/gestion/admin.py
@@ -0,0 +1,9 @@
+from django.contrib import admin
+
+# Register your models here.
+
+
+from .models import Autor, Libro
+
+admin.site.register(Autor)
+admin.site.register(Libro)
diff --git a/Django/mysite/polls/apps.py b/Libros/biblioteca/gestion/apps.py
similarity index 63%
rename from Django/mysite/polls/apps.py
rename to Libros/biblioteca/gestion/apps.py
index 5a5f94c..9fab178 100644
--- a/Django/mysite/polls/apps.py
+++ b/Libros/biblioteca/gestion/apps.py
@@ -1,6 +1,6 @@
from django.apps import AppConfig
-class PollsConfig(AppConfig):
+class GestionConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
- name = 'polls'
+ name = 'gestion'
diff --git a/Libros/biblioteca/gestion/forms.py b/Libros/biblioteca/gestion/forms.py
new file mode 100644
index 0000000..783a1bf
--- /dev/null
+++ b/Libros/biblioteca/gestion/forms.py
@@ -0,0 +1,12 @@
+from django import forms
+from .models import Autor, Libro
+
+class AutorForm(forms.ModelForm):
+ class Meta:
+ model = Autor
+ fields = ['nombre', 'biografia', 'foto']
+
+class LibroForm(forms.ModelForm):
+ class Meta:
+ model = Libro
+ fields = ['titulo', 'autor', 'fecha_publicacion', 'descripcion', 'archivo', 'portada']
diff --git a/Libros/biblioteca/gestion/migrations/0001_initial.py b/Libros/biblioteca/gestion/migrations/0001_initial.py
new file mode 100644
index 0000000..42193b5
--- /dev/null
+++ b/Libros/biblioteca/gestion/migrations/0001_initial.py
@@ -0,0 +1,34 @@
+# Generated by Django 5.0.7 on 2024-08-05 09:29
+
+import django.db.models.deletion
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Autor',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('nombre', models.CharField(max_length=200)),
+ ('biografia', models.TextField(blank=True, null=True)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='Libro',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('titulo', models.CharField(max_length=200)),
+ ('fecha_publicacion', models.DateField()),
+ ('descripcion', models.TextField(blank=True, null=True)),
+ ('archivo', models.FileField(upload_to='libros/')),
+ ('autor', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='gestion.autor')),
+ ],
+ ),
+ ]
diff --git a/Libros/biblioteca/gestion/migrations/0002_alter_libro_fecha_publicacion.py b/Libros/biblioteca/gestion/migrations/0002_alter_libro_fecha_publicacion.py
new file mode 100644
index 0000000..fb30d3a
--- /dev/null
+++ b/Libros/biblioteca/gestion/migrations/0002_alter_libro_fecha_publicacion.py
@@ -0,0 +1,20 @@
+# Generated by Django 5.0.7 on 2024-08-05 10:17
+
+import django.core.validators
+import gestion.models
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('gestion', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='libro',
+ name='fecha_publicacion',
+ field=models.PositiveBigIntegerField(default=2024, validators=[django.core.validators.MinValueValidator(1984), gestion.models.max_value_current_year]),
+ ),
+ ]
diff --git a/Libros/biblioteca/gestion/migrations/0003_libro_portada.py b/Libros/biblioteca/gestion/migrations/0003_libro_portada.py
new file mode 100644
index 0000000..3294c48
--- /dev/null
+++ b/Libros/biblioteca/gestion/migrations/0003_libro_portada.py
@@ -0,0 +1,18 @@
+# Generated by Django 5.0.7 on 2024-08-05 10:24
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('gestion', '0002_alter_libro_fecha_publicacion'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='libro',
+ name='portada',
+ field=models.ImageField(blank=True, null=True, upload_to='portadas/'),
+ ),
+ ]
diff --git a/Libros/biblioteca/gestion/migrations/0004_autor_foto.py b/Libros/biblioteca/gestion/migrations/0004_autor_foto.py
new file mode 100644
index 0000000..f46d19b
--- /dev/null
+++ b/Libros/biblioteca/gestion/migrations/0004_autor_foto.py
@@ -0,0 +1,18 @@
+# Generated by Django 5.0.7 on 2024-08-05 10:29
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('gestion', '0003_libro_portada'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='autor',
+ name='foto',
+ field=models.ImageField(blank=True, null=True, upload_to='autores/'),
+ ),
+ ]
diff --git a/Django/mysite/polls/migrations/__init__.py b/Libros/biblioteca/gestion/migrations/__init__.py
similarity index 100%
rename from Django/mysite/polls/migrations/__init__.py
rename to Libros/biblioteca/gestion/migrations/__init__.py
diff --git a/Libros/biblioteca/gestion/models.py b/Libros/biblioteca/gestion/models.py
new file mode 100644
index 0000000..c4c8aeb
--- /dev/null
+++ b/Libros/biblioteca/gestion/models.py
@@ -0,0 +1,29 @@
+from django.db import models
+import datetime
+from django.core.validators import MaxValueValidator, MinValueValidator
+
+def current_year():
+ return datetime.date.today().year
+
+
+def max_value_current_year(value):
+ return MaxValueValidator(current_year())(value)
+
+class Autor(models.Model):
+ nombre = models.CharField(max_length=200)
+ biografia = models.TextField(blank=True, null=True)
+ foto = models.ImageField(upload_to='autores/', blank=True, null=True) # Nuevo campo
+
+ def __str__(self):
+ return self.nombre
+
+class Libro(models.Model):
+ titulo = models.CharField(max_length=200)
+ autor = models.ForeignKey(Autor, on_delete=models.CASCADE)
+ fecha_publicacion = models.PositiveBigIntegerField(default=current_year(), validators=[MinValueValidator(1984), max_value_current_year])
+ descripcion = models.TextField(blank=True, null=True)
+ archivo = models.FileField(upload_to='libros/')
+ portada = models.ImageField(upload_to='portadas/', blank=True, null=True) # Nuevo campo
+
+ def __str__(self):
+ return self.titulo
diff --git a/Libros/biblioteca/gestion/templates/gestion/detalle_autor.html b/Libros/biblioteca/gestion/templates/gestion/detalle_autor.html
new file mode 100644
index 0000000..e674bea
--- /dev/null
+++ b/Libros/biblioteca/gestion/templates/gestion/detalle_autor.html
@@ -0,0 +1,14 @@
+
+
+
+ Detalle del Autor
+
+
+ {{ autor.nombre }}
+ {{ autor.biografia }}
+ {% if autor.foto %}
+
+ {% endif %}
+ Volver a la lista de autores
+
+
diff --git a/Libros/biblioteca/gestion/templates/gestion/detalle_libro.html b/Libros/biblioteca/gestion/templates/gestion/detalle_libro.html
new file mode 100644
index 0000000..4f15b77
--- /dev/null
+++ b/Libros/biblioteca/gestion/templates/gestion/detalle_libro.html
@@ -0,0 +1,18 @@
+
+
+
+ Detalle del Libro
+
+
+ {{ libro.titulo }}
+ {{ libro.descripcion }}
+ Autor: {{ libro.autor.nombre }}
+ Fecha de Publicación: {{ libro.fecha_publicacion }}
+ {% if libro.portada %}
+
+ {% endif %}
+ {% if libro.archivo %}
+ Descargar
+ {% endif %} Volver a la lista de libros
+
+
diff --git a/Libros/biblioteca/gestion/templates/gestion/form_autor.html b/Libros/biblioteca/gestion/templates/gestion/form_autor.html
new file mode 100644
index 0000000..fa0f805
--- /dev/null
+++ b/Libros/biblioteca/gestion/templates/gestion/form_autor.html
@@ -0,0 +1,15 @@
+
+
+
+ Formulario de Autor
+
+
+ {% if form.instance.pk %}Editar Autor{% else %}Nuevo Autor{% endif %}
+
+ Cancelar
+
+
diff --git a/Libros/biblioteca/gestion/templates/gestion/form_libro.html b/Libros/biblioteca/gestion/templates/gestion/form_libro.html
new file mode 100644
index 0000000..a53786b
--- /dev/null
+++ b/Libros/biblioteca/gestion/templates/gestion/form_libro.html
@@ -0,0 +1,15 @@
+
+
+
+ Formulario de Libro
+
+
+ {% if form.instance.pk %}Editar Libro{% else %}Nuevo Libro{% endif %}
+
+ Cancelar
+
+
diff --git a/Libros/biblioteca/gestion/templates/gestion/lista_autores.html b/Libros/biblioteca/gestion/templates/gestion/lista_autores.html
new file mode 100644
index 0000000..83e5d0a
--- /dev/null
+++ b/Libros/biblioteca/gestion/templates/gestion/lista_autores.html
@@ -0,0 +1,19 @@
+
+
+
+ Lista de Autores
+
+
+ Lista de Autores
+ Nuevo Autor
+
+
+
diff --git a/Libros/biblioteca/gestion/templates/gestion/lista_libros.html b/Libros/biblioteca/gestion/templates/gestion/lista_libros.html
new file mode 100644
index 0000000..dd338fb
--- /dev/null
+++ b/Libros/biblioteca/gestion/templates/gestion/lista_libros.html
@@ -0,0 +1,19 @@
+
+
+
+ Lista de Libros
+
+
+ Lista de Libros
+ Nuevo Libro
+
+
+
diff --git a/Libros/biblioteca/gestion/tests.py b/Libros/biblioteca/gestion/tests.py
new file mode 100644
index 0000000..7ce503c
--- /dev/null
+++ b/Libros/biblioteca/gestion/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/Libros/biblioteca/gestion/urls.py b/Libros/biblioteca/gestion/urls.py
new file mode 100644
index 0000000..2edf7ba
--- /dev/null
+++ b/Libros/biblioteca/gestion/urls.py
@@ -0,0 +1,16 @@
+from django.urls import path
+from . import views
+
+urlpatterns = [
+ path('autores/', views.lista_autores, name='lista_autores'),
+ path('autores/nuevo/', views.nuevo_autor, name='nuevo_autor'),
+ path('autores//', views.detalle_autor, name='detalle_autor'),
+ path('autores//editar/', views.editar_autor, name='editar_autor'),
+ path('autores//eliminar/', views.eliminar_autor, name='eliminar_autor'),
+
+ path('libros/', views.lista_libros, name='lista_libros'),
+ path('libros/nuevo/', views.nuevo_libro, name='nuevo_libro'),
+ path('libros//', views.detalle_libro, name='detalle_libro'),
+ path('libros//editar/', views.editar_libro, name='editar_libro'),
+ path('libros//eliminar/', views.eliminar_libro, name='eliminar_libro'),
+]
diff --git a/Libros/biblioteca/gestion/views.py b/Libros/biblioteca/gestion/views.py
new file mode 100644
index 0000000..a634a88
--- /dev/null
+++ b/Libros/biblioteca/gestion/views.py
@@ -0,0 +1,73 @@
+from django.shortcuts import render, get_object_or_404, redirect
+from .models import Autor, Libro
+from .forms import AutorForm, LibroForm
+
+# Vistas para los autores
+def lista_autores(request):
+ autores = Autor.objects.all()
+ return render(request, 'gestion/lista_autores.html', {'autores': autores})
+
+def detalle_autor(request, autor_id):
+ autor = get_object_or_404(Autor, pk=autor_id)
+ return render(request, 'gestion/detalle_autor.html', {'autor': autor})
+
+def nuevo_autor(request):
+ if request.method == 'POST':
+ form = AutorForm(request.POST, request.FILES)
+ if form.is_valid():
+ form.save()
+ return redirect('lista_autores')
+ else:
+ form = AutorForm()
+ return render(request, 'gestion/form_autor.html', {'form': form})
+
+def editar_autor(request, autor_id):
+ autor = get_object_or_404(Autor, pk=autor_id)
+ if request.method == 'POST':
+ form = AutorForm(request.POST, request.FILES, instance=autor)
+ if form.is_valid():
+ form.save()
+ return redirect('lista_autores')
+ else:
+ form = AutorForm(instance=autor)
+ return render(request, 'gestion/form_autor.html', {'form': form})
+
+def eliminar_autor(request, autor_id):
+ autor = get_object_or_404(Autor, pk=autor_id)
+ autor.delete()
+ return redirect('lista_autores')
+
+# Vistas para los libros
+def lista_libros(request):
+ libros = Libro.objects.all()
+ return render(request, 'gestion/lista_libros.html', {'libros': libros})
+
+def detalle_libro(request, libro_id):
+ libro = get_object_or_404(Libro, pk=libro_id)
+ return render(request, 'gestion/detalle_libro.html', {'libro': libro})
+
+def nuevo_libro(request):
+ if request.method == 'POST':
+ form = LibroForm(request.POST, request.FILES)
+ if form.is_valid():
+ form.save()
+ return redirect('lista_libros')
+ else:
+ form = LibroForm()
+ return render(request, 'gestion/form_libro.html', {'form': form})
+
+def editar_libro(request, libro_id):
+ libro = get_object_or_404(Libro, pk=libro_id)
+ if request.method == 'POST':
+ form = LibroForm(request.POST, request.FILES, instance=libro)
+ if form.is_valid():
+ form.save()
+ return redirect('lista_libros')
+ else:
+ form = LibroForm(instance=libro)
+ return render(request, 'gestion/form_libro.html', {'form': form})
+
+def eliminar_libro(request, libro_id):
+ libro = get_object_or_404(Libro, pk=libro_id)
+ libro.delete()
+ return redirect('lista_libros')
diff --git a/Libros/biblioteca/libros/Invisible_-_Paul_Auster_5.epub b/Libros/biblioteca/libros/Invisible_-_Paul_Auster_5.epub
new file mode 100644
index 0000000..6469261
Binary files /dev/null and b/Libros/biblioteca/libros/Invisible_-_Paul_Auster_5.epub differ
diff --git a/Libros/biblioteca/libros/Sunset_Park_-_Paul_Auster_12.epub b/Libros/biblioteca/libros/Sunset_Park_-_Paul_Auster_12.epub
new file mode 100644
index 0000000..dcb4e04
Binary files /dev/null and b/Libros/biblioteca/libros/Sunset_Park_-_Paul_Auster_12.epub differ
diff --git a/Django/mysite/manage.py b/Libros/biblioteca/manage.py
similarity index 88%
rename from Django/mysite/manage.py
rename to Libros/biblioteca/manage.py
index a7da667..c85cb37 100755
--- a/Django/mysite/manage.py
+++ b/Libros/biblioteca/manage.py
@@ -6,7 +6,7 @@ import sys
def main():
"""Run administrative tasks."""
- os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
+ os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'biblioteca.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
diff --git a/Libros/biblioteca/portadas/sunsetpark.jpeg b/Libros/biblioteca/portadas/sunsetpark.jpeg
new file mode 100644
index 0000000..0f249cd
Binary files /dev/null and b/Libros/biblioteca/portadas/sunsetpark.jpeg differ