-
-
Notifications
You must be signed in to change notification settings - Fork 317
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1057 from AnkurPrabhu/new-download-fix
new-download-fix
- Loading branch information
Showing
22 changed files
with
290 additions
and
81 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
import io | ||
import os | ||
import uuid | ||
import zipfile | ||
from datetime import datetime | ||
|
||
import pytz | ||
from django.conf import settings | ||
from django.utils import timezone | ||
from django_q.tasks import AsyncTask, schedule | ||
|
||
import api.util as util | ||
from api.models.long_running_job import LongRunningJob | ||
|
||
|
||
def create_download_job(job_type, user, photos, filename): | ||
job_id = uuid.uuid4() | ||
lrj = LongRunningJob.objects.create( | ||
started_by=user, | ||
job_id=job_id, | ||
queued_at=datetime.now().replace(tzinfo=pytz.utc), | ||
job_type=job_type, | ||
) | ||
if job_type == LongRunningJob.JOB_DOWNLOAD_PHOTOS: | ||
AsyncTask( | ||
zip_photos_task, job_id=job_id, user=user, photos=photos, filename=filename | ||
).run() | ||
|
||
lrj.save() | ||
return job_id | ||
|
||
|
||
def zip_photos_task(job_id, user, photos, filename): | ||
lrj = LongRunningJob.objects.get(job_id=job_id) | ||
lrj.started_at = datetime.now().replace(tzinfo=pytz.utc) | ||
count = len(photos) | ||
lrj.result = {"progress": {"current": 0, "target": count}} | ||
lrj.save() | ||
output_directory = os.path.join(settings.MEDIA_ROOT, "zip") | ||
zip_file_name = filename | ||
done_count = 0 | ||
try: | ||
if not os.path.exists(output_directory): | ||
os.mkdir(output_directory) | ||
mf = io.BytesIO() | ||
photos_name = {} | ||
|
||
for photo in photos.values(): | ||
done_count = done_count + 1 | ||
photo_name = os.path.basename(photo.main_file.path) | ||
if photo_name in photos_name: | ||
photos_name[photo_name] = photos_name[photo_name] + 1 | ||
photo_name = str(photos_name[photo_name]) + "-" + photo_name | ||
else: | ||
photos_name[photo_name] = 1 | ||
with zipfile.ZipFile(mf, mode="a", compression=zipfile.ZIP_DEFLATED) as zf: | ||
zf.write(photo.main_file.path, arcname=photo_name) | ||
lrj.result = {"progress": {"current": done_count, "target": count}} | ||
lrj.save() | ||
with open(os.path.join(output_directory, zip_file_name), "wb") as output_file: | ||
output_file.write(mf.getvalue()) | ||
|
||
except Exception as e: | ||
util.logger.error("Error while converting files to zip: {}".format(e)) | ||
|
||
lrj.finished_at = datetime.now().replace(tzinfo=pytz.utc) | ||
lrj.finished = True | ||
lrj.save() | ||
# scheduling a task to delete the zip file after a day | ||
execution_time = timezone.now() + timezone.timedelta(days=1) | ||
schedule("api.all_tasks.delete_zip_file", filename, next_run=execution_time) | ||
return os.path.join(output_directory, zip_file_name) | ||
|
||
|
||
def delete_zip_file(filename): | ||
file_path = os.path.join(settings.MEDIA_ROOT, "zip", filename) | ||
try: | ||
if not os.path.exists(file_path): | ||
util.logger.error( | ||
"Error while deleting file not found at : {}".format(file_path) | ||
) | ||
return | ||
else: | ||
os.remove(file_path) | ||
util.logger.info("file deleted sucessfully at path : {}".format(file_path)) | ||
return | ||
|
||
except Exception as e: | ||
util.logger.error("Error while deleting file: {}".format(e)) | ||
return e |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
import requests | ||
import numpy as np | ||
import requests | ||
|
||
|
||
def get_face_encodings(image_path, known_face_locations): | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# Generated by Django 4.2.6 on 2023-10-27 13:01 | ||
|
||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
dependencies = [ | ||
("api", "0054_user_cluster_selection_epsilon_user_min_samples"), | ||
] | ||
|
||
operations = [ | ||
migrations.AlterField( | ||
model_name="longrunningjob", | ||
name="job_type", | ||
field=models.PositiveIntegerField( | ||
choices=[ | ||
(1, "Scan Photos"), | ||
(2, "Generate Event Albums"), | ||
(3, "Regenerate Event Titles"), | ||
(4, "Train Faces"), | ||
(5, "Delete Missing Photos"), | ||
(7, "Scan Faces"), | ||
(6, "Calculate Clip Embeddings"), | ||
(8, "Find Similar Faces"), | ||
(9, "Download Selected Photos"), | ||
] | ||
), | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,34 +1,28 @@ | ||
|
||
from django.utils import timezone | ||
from unittest.mock import patch | ||
from django.test import TestCase | ||
from django.utils import timezone | ||
from rest_framework.test import APIClient | ||
from api.models.album_date import AlbumDate | ||
from api.tests.utils import create_test_photos, create_test_user,create_test_photo | ||
|
||
|
||
from api.models.album_date import AlbumDate | ||
from api.tests.utils import create_test_photo, create_test_user | ||
|
||
|
||
class OnlyPhotosOrOnlyVideosTest(TestCase): | ||
def setUp(self): | ||
self.client = APIClient() | ||
self.user = create_test_user() | ||
self.client.force_authenticate(user=self.user) | ||
|
||
def test_only_photos(self): | ||
now = timezone.now() | ||
photo= create_test_photo( owner=self.user, added_on=now,public=True) | ||
photo = create_test_photo(owner=self.user, added_on=now, public=True) | ||
|
||
album=AlbumDate(owner=self.user) | ||
album.id=1 | ||
album = AlbumDate(owner=self.user) | ||
album.id = 1 | ||
album.photos.add(photo) | ||
album.save() | ||
|
||
response = self.client.get("/api/albums/date/list?photo=true").url | ||
response =self.client.get(response) | ||
response = self.client.get(response) | ||
|
||
data = response.json() | ||
self.assertEqual(1, len(data["results"])) | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
from unittest.mock import patch | ||
|
||
from django.test import TestCase | ||
from django.utils import timezone | ||
from rest_framework.test import APIClient | ||
|
||
from api.models.long_running_job import LongRunningJob | ||
from api.tests.utils import create_test_photos, create_test_user | ||
|
||
|
||
class PhotoListWithoutTimestampTest(TestCase): | ||
def setUp(self): | ||
self.client = APIClient() | ||
self.user = create_test_user() | ||
self.client.force_authenticate(user=self.user) | ||
|
||
@patch("shutil.disk_usage") | ||
def test_download(self, patched_shutil): | ||
# test download function when we have enough storage | ||
patched_shutil.return_value.free = 500000000 | ||
now = timezone.now() | ||
create_test_photos(number_of_photos=1, owner=self.user, added_on=now, size=100) | ||
|
||
response = self.client.get("/api/photos/notimestamp/") | ||
img_hash = response.json()["results"][0]["url"] | ||
datadict = {"owner": self.user, "image_hashes": [img_hash]} | ||
|
||
response_2 = self.client.post("/api/photos/download", data=datadict) | ||
lrr_job = LongRunningJob.objects.all()[0] | ||
self.assertEqual(lrr_job.job_id, response_2.json()["job_id"]) | ||
self.assertEqual(response_2.status_code, 200) | ||
|
||
# test download function when we dont have enough storage | ||
patched_shutil.return_value.free = 0 | ||
response_3 = self.client.post("/api/photos/download", data=datadict) | ||
self.assertEqual(response_3.status_code, 507) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.