Skip to content

Commit

Permalink
Merge branch '2.2.2' into release
Browse files Browse the repository at this point in the history
  • Loading branch information
jayvarner committed Dec 2, 2021
2 parents 5f1ec42 + a941bde commit 078637f
Show file tree
Hide file tree
Showing 29 changed files with 424 additions and 262 deletions.
2 changes: 2 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
[report]
omit =
*tests.py
*celery.py
*tests/*
apps/cms/*
apps/contrib/*
apps/utils/fake_traceback.py
*migrations*
# Exclude tasks
*tasks.py
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

CHANGELOG
=========
Release 2.2.2
---------------------
* Bug fixes for naming GitHub repository for export.

Release 2.2.1
---------------------
* Improvements to bulk ingest
Expand Down
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
source 'https://rubygems.org'

gem 'iiif_to_jekyll', '0.9.4', git: 'https://github.com/ecds/iiif-to-jekyll.git'
gem 'iiif_to_jekyll', '0.9.5', git: 'https://github.com/ecds/iiif-to-jekyll.git'
44 changes: 30 additions & 14 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,46 +1,62 @@
GIT
remote: https://github.com/ecds/iiif-to-jekyll.git
revision: 6f734546fe58c8d24ab07d24d29eee43a564a701
revision: de5365cd30e5b70756328f2d584e0400c70eaf47
specs:
iiif_to_jekyll (0.9.4)
iiif_to_jekyll (0.9.5)
iiif-presentation (~> 0.2.0)
openssl

GEM
remote: https://rubygems.org/
specs:
activesupport (6.1.0)
activesupport (6.1.4.1)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
zeitwerk (~> 2.3)
concurrent-ruby (1.1.7)
faraday (1.3.0)
concurrent-ruby (1.1.9)
faraday (1.8.0)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
faraday-excon (~> 1.1)
faraday-httpclient (~> 1.0.1)
faraday-net_http (~> 1.0)
faraday-net_http_persistent (~> 1.1)
faraday-patron (~> 1.0)
faraday-rack (~> 1.0)
multipart-post (>= 1.2, < 3)
ruby2_keywords
faraday-net_http (1.0.0)
i18n (1.8.7)
ruby2_keywords (>= 0.0.4)
faraday-em_http (1.0.0)
faraday-em_synchrony (1.0.0)
faraday-excon (1.1.0)
faraday-httpclient (1.0.1)
faraday-net_http (1.0.1)
faraday-net_http_persistent (1.2.0)
faraday-patron (1.0.0)
faraday-rack (1.0.0)
i18n (1.8.11)
concurrent-ruby (~> 1.0)
iiif-presentation (0.2.0)
activesupport (>= 3.2.18)
faraday (>= 0.9)
json
json (2.5.1)
minitest (5.14.2)
ipaddr (1.2.3)
json (2.6.1)
minitest (5.14.4)
multipart-post (2.1.1)
openssl (2.2.0)
ruby2_keywords (0.0.2)
openssl (2.2.1)
ipaddr
ruby2_keywords (0.0.5)
tzinfo (2.0.4)
concurrent-ruby (~> 1.0)
zeitwerk (2.4.2)
zeitwerk (2.5.1)

PLATFORMS
ruby

DEPENDENCIES
iiif_to_jekyll (= 0.9.4)!
iiif_to_jekyll (= 0.9.5)!

BUNDLED WITH
2.1.4
2 changes: 1 addition & 1 deletion apps/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = "2.2.1"
__version__ = "2.2.2"
__version_info__ = tuple(
[
int(num) if num.isdigit() else num
Expand Down
16 changes: 16 additions & 0 deletions apps/export/celery.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"""
Celery config for ingest tasks.
"""
import os
from celery import Celery
from django.conf import settings
# import config.settings.local as settings

# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings.local')
app = Celery('apps.export', result_extended=True)

# Using a string here means the worker will not have to
# pickle the object when using Windows.
app.config_from_object('django.conf:settings')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
2 changes: 1 addition & 1 deletion apps/export/export.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# pylint: disable = unused-import, ungrouped-imports
try:
from yaml import CLoader as Loader, CDumper as Dumper
except ImportError:
except ImportError: # pragma: no cover
from yaml import Loader, Dumper
# pylint: enable = unused-import, ungrouped-imports
# TODO: Can we be more efficient in how we import git?
Expand Down
68 changes: 68 additions & 0 deletions apps/export/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
"""Django Forms for export."""
import logging
from django import forms
from django.contrib.admin import site as admin_site, widgets

from apps.iiif.kollections.models import Collection
from apps.iiif.manifests.models import Manifest
from apps.iiif.canvases.models import Canvas

LOGGER = logging.getLogger(__name__)

# add is_checkbox method to all form fields, to enable template logic.
# thanks to:
# http://stackoverflow.com/questions/3927018/django-how-to-check-if-field-widget-is-checkbox-in-the-template
setattr(
forms.Field,
'is_checkbox',
lambda self: isinstance(self.widget, forms.CheckboxInput)
)

class JekyllExportForm(forms.Form):
"""Form to provide export options."""
#: export mode
mode = forms.ChoiceField(
label='Export mode',
choices=[
('download', 'Download Jekyll site export'),
('github', 'Publish Jekyll site on GitHub'),
],
initial='none',
widget=forms.RadioSelect(attrs={'class': 'uk-radio'}),
help_text='Choose how to export your annotated volume.'
)
#: help text for export mode choices
mode_help = [
'Download a zip file with all Jekyll site contents',
'''Create or update a GitHub repository with the generated Jekyll
site content and publish it using Github Pages'''
]

#: github repository name to be created
github_repo = forms.SlugField(
label='GitHub repository name', required=False,
widget=forms.TextInput(attrs={'class': 'rdx-input uk-input'}),
help_text='Name of the repository to be created or updated, which will also ' +
'determine the GitHub pages URL.')

#: options that are relevant to jekyll export but not to TEI
jekyll_options = [
# 'page_one',
# 'deep_zoom',
# 'image_hosting'
]

# flag to allow suppressing annotation choice display when
# user does not belong to any annotation groups
hide_annotation_choice = False

def __init__(self, user, *args, **kwargs):
self.user = user

# initialize normally
super(JekyllExportForm, self).__init__(*args, **kwargs)
# If the person has not authorized GitHub access, remove the GitHub
# options and select download by default.
if 'github' not in user.socialaccount_list:
self.fields['mode'].choices = self.fields['mode'].choices[:1]
self.fields['mode'].widget.attrs = {'class': 'uk-radio', 'checked': True}
6 changes: 4 additions & 2 deletions apps/export/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@

LOGGER = logging.getLogger(__name__)

app = Celery('apps.readux', result_extended=True)
app = Celery('apps.export', result_extended=True)
app.config_from_object('django.conf:settings')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)

@app.task(name='github_export', autoretry_for=(Exception,), retry_backoff=True, max_retries=20)
def github_export_task(
Expand Down Expand Up @@ -81,7 +83,7 @@ def download_export_task(
)

zipfile_name = jekyll_exporter.download_export(user.email, manifest)
delete_download_task.apply_async((zipfile_name), countdown=86400)
delete_download_task.apply_async((zipfile_name,), countdown=86400)
LOGGER.info('Background download export finished.')

@app.task(name='delete_download', autoretry_for=(Exception,), retry_backoff=True, max_retries=20)
Expand Down
40 changes: 34 additions & 6 deletions apps/export/tests/test_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,20 @@
import tempfile
import zipfile
import httpretty
from slugify import slugify
from django.test import TestCase, Client
from django.test import RequestFactory
from django.conf import settings
from django.contrib.auth import get_user_model
from django.urls import reverse
from apps.iiif.manifests.models import Manifest
from apps.iiif.manifests.views import ManifestExport, JekyllExport
from apps.iiif.canvases.models import Canvas
from apps.export.export import IiifManifestExport, JekyllSiteExport, GithubExportException, ExportException
from apps.export.github import GithubApi
from apps.users.tests.factories import UserFactory, SocialAccountFactory, SocialAppFactory, SocialTokenFactory
from iiif_prezi.loader import ManifestReader
from apps.users.tests.factories import SocialAccountFactory, SocialAppFactory, SocialTokenFactory
from apps.export.views import JekyllExport, ManifestExport

User = get_user_model()


class ManifestExportTests(TestCase):
fixtures = ['users.json', 'kollections.json', 'manifests.json', 'canvases.json', 'annotations.json', 'userannotation.json']

Expand Down Expand Up @@ -184,7 +182,34 @@ def test_jekyll_export_include_download(self):
assert isinstance(response.getvalue(), bytes)

@httpretty.httprettified(allow_net_connect=False)
def test_jekyll_export_to_github(self):
def test_jekyll_export_to_github_repo_name_has_spaces(self):
httpretty.register_uri(
httpretty.GET,
'https://api.github.com/users/{u}/repos?per_page=3'.format(u=self.jse.github_username),
body='[{"name":"marx"}]',
content_type="text/json"
)
httpretty.register_uri(
httpretty.POST, 'https://api.github.com/user/repos'
)
kwargs = {'pid': self.volume.pid, 'version': 'v2'}
url = reverse('JekyllExport', kwargs=kwargs)
kwargs['deep_zoom'] = 'exclude'
kwargs['mode'] = 'github'
kwargs['github_repo'] = 'has spaces'
request = self.factory.post(url, data=kwargs)
request.user = self.user
response = self.jekyll_export_view(
request,
pid=self.volume.pid,
version='v2',
content_type="application/x-www-form-urlencoded"
)
assert response.status_code == 200
assert 'https://github.com/zaphod/has-spaces' in response.content.decode('utf-8')

@httpretty.httprettified(allow_net_connect=False)
def test_jekyll_export_to_github_repo_name_not_given(self):
httpretty.register_uri(
httpretty.GET,
'https://api.github.com/users/{u}/repos?per_page=3'.format(u=self.jse.github_username),
Expand All @@ -198,6 +223,7 @@ def test_jekyll_export_to_github(self):
url = reverse('JekyllExport', kwargs=kwargs)
kwargs['deep_zoom'] = 'exclude'
kwargs['mode'] = 'github'
kwargs['github_repo'] = ''
request = self.factory.post(url, data=kwargs)
request.user = self.user
response = self.jekyll_export_view(
Expand All @@ -207,6 +233,8 @@ def test_jekyll_export_to_github(self):
content_type="application/x-www-form-urlencoded"
)
assert response.status_code == 200
assert f'https://github.com/zaphod/{slugify(self.volume.label, lowercase=False, max_length=50)}' in response.content.decode('utf-8')
assert f'https://zaphod.github.io/{slugify(self.volume.label, lowercase=False, max_length=50)}' in response.content.decode('utf-8')

def test_use_github(self):
assert isinstance(self.jse.github, GithubApi)
Expand Down
25 changes: 24 additions & 1 deletion apps/export/tests/test_github.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,16 @@ def test_get_oauth_scopes(self):
scopes = self.gh.oauth_scopes(test=True)
assert scopes == ['repo', 'user']

@httpretty.activate
def test_get_oauth_scopes_is_none(self):
httpretty.register_uri(
httpretty.GET,
'https://api.github.com/user',
status=404
)
scopes = self.gh.oauth_scopes(test=True)
assert scopes is None

@httpretty.activate
def test_create_repo(self):
httpretty.register_uri(httpretty.POST, 'https://api.github.com/user/repos', body='hello', status=201)
Expand All @@ -80,6 +90,19 @@ def test_list_repos(self):
repos = self.gh.list_repos('karl')
assert len(repos) == 6

@httpretty.activate
def test_list_user_repos_is_none(self):
httpretty.register_uri(
httpretty.GET,
'https://api.github.com/user/repos',
status=404
)

repos = self.gh.list_user_repos()
for _ in range(0, 20):
print(f'****{repos}')
assert repos is None

@httpretty.activate
def test_list_user_repos(self):
resp_body = '[{},{},{}]'
Expand Down Expand Up @@ -108,7 +131,7 @@ def test_create_pr(self):
body='{}',
status=201
)
pr = self.gh.create_pull_request('joseph', 'pitty', 'barco', 'larentowicz')
pr = self.gh.create_pull_request('joseph', 'pitty', 'barco', 'larentowicz', 'araujo')
assert pr == {}

@httpretty.activate
Expand Down
24 changes: 24 additions & 0 deletions apps/export/tests/test_views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'''
'''
from django.test import TestCase
from django.contrib.auth import get_user_model
from allauth.socialaccount.models import SocialAccount
from apps.export.forms import JekyllExportForm

class ManifestTests(TestCase):
fixtures = ['users.json']

def setUp(self):
self.user = get_user_model().objects.get(pk=111)

def test_form_mode_choices_no_github(self):
form = JekyllExportForm(user=self.user)
assert len(form.fields['mode'].choices) == 1
assert form.fields['mode'].choices[0] != 'github'

def test_form_mode_choices_with_github(self):
sa = SocialAccount(provider='github', user=self.user)
sa.save()
form = JekyllExportForm(user=self.user)
assert len(form.fields['mode'].choices) == 2
assert form.fields['mode'].choices[1][0] == 'github'
9 changes: 9 additions & 0 deletions apps/export/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"""URL patterns for manifests."""
from django.urls import path
from . import views

urlpatterns = [
path('iiif/<version>/<pid>/plain', views.PlainExport.as_view(), name="PlainExport"),
path('iiif/<version>/<pid>/export', views.ManifestExport.as_view(), name="ManifestExport"),
path('iiif/<version>/<pid>/jekyllexport', views.JekyllExport.as_view(), name="JekyllExport"),
]
Loading

0 comments on commit 078637f

Please sign in to comment.