From 8db0674f39b1a464ca66586989a3dcbb4bec7ca2 Mon Sep 17 00:00:00 2001 From: Reyhan Alhafizal Date: Fri, 9 Oct 2020 18:17:44 +0700 Subject: [PATCH 1/4] Fix merge conflict app/test & requirements --- app/tests.py | 4 +++- requirements.txt | 13 ++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/app/tests.py b/app/tests.py index 0be875f..1bf355a 100644 --- a/app/tests.py +++ b/app/tests.py @@ -1,4 +1,4 @@ -import json, tempfile, os +import json, tempfile, os, mock import pandas as pd from io import StringIO @@ -12,6 +12,8 @@ from django.core.files import File from django.core.exceptions import PermissionDenied, ValidationError from django.core.files.uploadedfile import SimpleUploadedFile from django.core.management import call_command +from django.test import Client, TestCase, TransactionTestCase +from django.urls import resolve, reverse from django.db.utils import IntegrityError from django.urls import resolve from django.test import Client, RequestFactory, TestCase, TransactionTestCase diff --git a/requirements.txt b/requirements.txt index 2dafe57..f3b2e12 100644 --- a/requirements.txt +++ b/requirements.txt @@ -29,13 +29,16 @@ entrypoints==0.3 filelock==3.0.12 flake8==3.7.9 flake8-isort==3.0.0 -google-api-core==1.17.0 -google-auth==1.14.1 +google-api-core==1.22.4 +google-api-python-client==1.12.3 +google-auth==1.22.1 +google-auth-httplib2==0.0.4 google-cloud-core==1.3.0 google-cloud-storage==1.28.0 google-resumable-media==0.5.0 googleapis-common-protos==1.51.0 gunicorn==20.0.4 +httplib2==0.18.1 identify==1.4.15 idna==2.9 importlib-metadata==1.5.2 @@ -43,16 +46,18 @@ importlib-resources==1.4.0 isort==4.3.21 lazy-object-proxy==1.4.3 mccabe==0.6.1 +mock==4.0.2 more-itertools==8.2.0 nodeenv==1.3.5 numpy==1.19.2 +oauth2client==4.1.3 packaging==20.3 pandas==1.1.3 pathspec==0.8.0 Pillow==7.1.1 pluggy==0.13.1 pre-commit==2.3.0 -protobuf==3.11.3 +protobuf==3.13.0 psycopg2==2.8.4 psycopg2-binary==2.8.6 py==1.8.1 @@ -60,6 +65,7 @@ pyasn1==0.4.8 pyasn1-modules==0.2.8 pycodestyle==2.5.0 pycparser==2.20 +PyDrive==1.3.1 pyflakes==2.1.1 pylint==2.4.4 pylint-django==2.0.15 @@ -82,6 +88,7 @@ sqlparse==0.3.1 testfixtures==6.14.1 toml==0.10.0 typed-ast==1.4.1 +uritemplate==3.0.1 urllib3==1.25.9 virtualenv==20.0.18 wcwidth==0.1.9 -- GitLab From b9118b80794aff02e9913e100111296dcfb866aa Mon Sep 17 00:00:00 2001 From: Reyhan Alhafizal Date: Fri, 9 Oct 2020 18:18:40 +0700 Subject: [PATCH 2/4] [RED] Add failing test Share materi to Google Drive --- app/tests.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/app/tests.py b/app/tests.py index 1bf355a..fbdb1f1 100644 --- a/app/tests.py +++ b/app/tests.py @@ -278,6 +278,25 @@ class DetailMateriTest(TestCase): self.assertIn(expected, response.context["citationAPA"]) + def test_tombol_bagikan_google_drive(self): + response = Client().get(self.url) + self.assertContains(response, 'Google Drive') + + @mock.patch('app.views.upload_to_gdrive') + def test_save_to_gdrive_with_nonexistent_materi(self, mock_upload_to_gdrive): + response = self.client.get('/materi/%s/save-to-gdrive/' % 0) + mock_upload_to_gdrive.assert_not_called() + self.assertEqual(response.status_code, 404) + + @mock.patch('app.views.upload_to_gdrive') + def test_save_to_gdrive_with_valid_materi(self, mock_upload_to_gdrive): + response = self.client.get( + '/materi/%s/save-to-gdrive/' % self.materi1.id, follow=True) + last_url, status_code = response.redirect_chain[-1] + mock_upload_to_gdrive.assert_called_once() + self.assertEqual(last_url, '/materi/%d/' % self.materi1.id) + self.assertEqual(status_code, 302) + class PostsViewTest(TestCase): @classmethod -- GitLab From 3319445086b8df8ac1299346ff9f71b8db174c0c Mon Sep 17 00:00:00 2001 From: Reyhan Alhafizal Date: Fri, 9 Oct 2020 18:19:15 +0700 Subject: [PATCH 3/4] [GREEN] Implement Share materi to Google Drive --- .gitignore | 1 + app/templates/app/detail_materi.html | 2 ++ app/urls.py | 1 + app/views.py | 28 +++++++++++++++++++++++++++- 4 files changed, 31 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index a7a6bf2..c0739ce 100644 --- a/.gitignore +++ b/.gitignore @@ -206,6 +206,7 @@ db.sqlite3 .coverage htmlcov/ flowchart/ +client_secrets.json # Pycharm IDE .idea diff --git a/app/templates/app/detail_materi.html b/app/templates/app/detail_materi.html index 54b0bb0..46b3416 100644 --- a/app/templates/app/detail_materi.html +++ b/app/templates/app/detail_materi.html @@ -206,6 +206,8 @@ Whatsapp Line + Google Drive
diff --git a/app/urls.py b/app/urls.py index a0230cf..7ccc70c 100644 --- a/app/urls.py +++ b/app/urls.py @@ -33,4 +33,5 @@ urlpatterns = [ path("profil//", KatalogPerKontributorView.as_view(), name="katalog-per-kontributor"), path("materi/rate/", views.add_rating_materi, name="rate-materi"), + path("materi//save-to-gdrive/", views.save_to_gdrive, name="save-to-gdrive"), ] diff --git a/app/views.py b/app/views.py index 0058033..fcbc5e3 100644 --- a/app/views.py +++ b/app/views.py @@ -9,6 +9,7 @@ from django.core.paginator import Paginator from django.db.models import Q, Count from django.http import (Http404, HttpResponse, HttpResponseRedirect, JsonResponse) +from django.urls import reverse from django.shortcuts import get_object_or_404, redirect from django.template import loader from django.urls import reverse @@ -25,7 +26,9 @@ import django import pandas as pd from io import BytesIO from django.contrib import messages - +from pydrive.auth import GoogleAuth +from pydrive.drive import GoogleDrive +from pydrive.auth import AuthenticationRejected def permission_denied(request, exception, template_name = 'error_403.html'): return defaults.permission_denied(request, exception, template_name) @@ -786,3 +789,26 @@ class DownloadHistoryView(TemplateView): context["riwayat_list"] = riwayat_list context["user_name"] = 'Guest' return self.render_to_response(context) + +def upload_to_gdrive(file_path, title): + gauth = GoogleAuth() + gauth.LocalWebserverAuth() + + drive = GoogleDrive(gauth) + file1 = drive.CreateFile() + file1.SetContentFile(file_path) + file1['title'] = title + print('title: %s, mimeType: %s' % (file1['title'], file1['mimeType'])) + file1.Upload() + +def save_to_gdrive(request, pk): + materi = get_object_or_404(Materi, pk=pk) + path = materi.content.path + file_path = os.path.join(settings.MEDIA_ROOT, path) + if os.path.exists(file_path): + with open(file_path, "rb") as fh: + upload_to_gdrive(file_path, materi.title) + else: + raise Http404("File tidak dapat ditemukan.") + + return HttpResponseRedirect(reverse('detail-materi', kwargs={'pk': pk})) -- GitLab From 789af9afd767a71e4591ca6f928f3feb06c2e743 Mon Sep 17 00:00:00 2001 From: Reyhan Alhafizal Date: Fri, 9 Oct 2020 23:22:09 +0700 Subject: [PATCH 4/4] Fix codesmell on Share Google Drive #50 Implementation --- app/tests.py | 5 ++--- app/views.py | 3 +-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/app/tests.py b/app/tests.py index fed0483..e2b1dfc 100644 --- a/app/tests.py +++ b/app/tests.py @@ -13,7 +13,7 @@ from django.core.exceptions import PermissionDenied, ValidationError from django.core.files.uploadedfile import SimpleUploadedFile from django.core.management import call_command from django.test import Client, TestCase, TransactionTestCase -from django.urls import resolve, reverse +from django.urls import resolve from django.db.utils import IntegrityError from django.test import Client, RequestFactory, TestCase, TransactionTestCase from pytz import timezone @@ -427,13 +427,12 @@ class DetailMateriTest(TestCase): @mock.patch("app.views.upload_to_gdrive") def test_save_to_gdrive_with_valid_materi(self, mock_upload_to_gdrive): - response = self.client.get("/zmateri/%s/save-to-gdrive/" % self.materi1.id, follow=True) + response = self.client.get("/materi/%s/save-to-gdrive/" % self.materi1.id, follow=True) last_url, status_code = response.redirect_chain[-1] mock_upload_to_gdrive.assert_called_once() self.assertEqual(last_url, "/materi/%d/" % self.materi1.id) self.assertEqual(status_code, 302) - class PostsViewTest(TestCase): @classmethod def generate_posts_data(cls, user): diff --git a/app/views.py b/app/views.py index f8bdfa2..f79dcec 100644 --- a/app/views.py +++ b/app/views.py @@ -849,8 +849,7 @@ def save_to_gdrive(request, pk): path = materi.content.path file_path = os.path.join(settings.MEDIA_ROOT, path) if os.path.exists(file_path): - with open(file_path, "rb") as fh: - upload_to_gdrive(file_path, materi.title) + upload_to_gdrive(file_path, materi.title) else: raise Http404("File tidak dapat ditemukan.") -- GitLab