Skip to content
This repository has been archived by the owner on May 30, 2018. It is now read-only.

Commit

Permalink
Massive refactorization (split code into modules)
Browse files Browse the repository at this point in the history
  • Loading branch information
timoguic committed Mar 31, 2018
1 parent aff44c6 commit a1fed27
Show file tree
Hide file tree
Showing 54 changed files with 672 additions and 571 deletions.
Empty file added drf_sp_hub/article/__init__.py
Empty file.
8 changes: 8 additions & 0 deletions drf_sp_hub/article/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from django.contrib import admin

from .models import Article

class ArticleAdmin(admin.ModelAdmin):
list_display = ('title', 'html_file', 'pk', 'id_senspublic')

admin.site.register(Article, ArticleAdmin)
8 changes: 8 additions & 0 deletions drf_sp_hub/article/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from django.apps import AppConfig


class ArticleConfig(AppConfig):
name = 'article'

def ready(self):
import article.signals
13 changes: 13 additions & 0 deletions drf_sp_hub/article/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from django import forms
from datetimewidget.widgets import DateTimeWidget

from .models import Article

class ArticleForm(forms.ModelForm):
class Meta:
model = Article
fields = [ 'title', 'html_file', 'pdf_file', 'keywords', 'type_article', 'published_on', 'published' ]
widgets = {
'keywords': forms.SelectMultiple(attrs={'class': 'select-multi-keywords, form-control'}),
'published_on': DateTimeWidget(attrs={'id':"yourdatetimeid"}, usel10n = True),
}
47 changes: 47 additions & 0 deletions drf_sp_hub/article/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
from django.db import models
from django.conf import settings

from django.utils.timezone import now as tznow
from django.contrib.postgres.fields import JSONField
from enumfields import EnumIntegerField
from enumfields import Enum

class ArticleType(Enum):
UNKNOWN = 0
ESSAI = 1
CHRONIQUE = 2
CREATION = 3
ENTRETIEN = 4
LECTURE = 5
SOMMAIRE_DOSSIER = 6

class Labels:
UNKNOWN = 'Inconnu'
SOMMAIRE_DOSSIER = 'Sommaire dossier'

class Article(models.Model):
title = models.CharField(max_length=200, null=False, blank=False)
created_by = models.ForeignKey(settings.AUTH_USER_MODEL, default=1, on_delete=models.SET_DEFAULT, related_name='owned_articles', null=False, blank=False)
created_on = models.DateTimeField('created date', auto_now_add=True, blank=False)
published_on = models.DateTimeField('published date', default=tznow, null=False, blank=False)
published = models.BooleanField(null=False, blank=False, default=False, db_index=True)

html_file = models.FileField(upload_to='articles/', null=True, blank=True)
id_senspublic = models.IntegerField(null=True, blank=True, unique=True, db_index=True)
pdf_file = models.FileField(upload_to='articles/', null=True, blank=True)

authors = JSONField(null=True, blank=True)

keywords = models.ManyToManyField('spkeyword.SPKeyword', related_name='articles', blank=True)
type_article = EnumIntegerField(ArticleType, default=ArticleType.UNKNOWN)

class Meta:
permissions = (
('read_unpublished_articles', 'Can read unpublished articles'),
)

def get_absolute_url(self):
return reverse('display_article', kwargs={'pk': self.pk})

def __str__(self):
return self.title
60 changes: 60 additions & 0 deletions drf_sp_hub/article/signals.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import logging
import os
import re
from lxml import etree

from django.utils.html import strip_tags

from django.db.models.signals import post_save, post_delete, pre_save
from django.dispatch import receiver

from .models import Article

from sp_app.utils.html_importer import HTMLImporter

logger = logging.getLogger(__name__)

# Update keywords and article based on HTML file
@receiver(post_save, sender=Article)
def update_article_from_html_file(sender, instance, created, **kwargs):

if not instance.html_file:
return False

id_senspublic = re.findall(r'SP(\d+).html', os.path.basename(instance.html_file.path))
if len(id_senspublic) == 1:
Article.objects.filter(pk=instance.pk).update(id_senspublic=id_senspublic[0])

importer = HTMLImporter(instance)
# Clear keywords, then match and associate
instance.keywords.clear()
importer.process_file()

# title = tree.xpath("//head/title")

# if title and len(title) is 1:
# t = title[0].text
# logger.info('Updating title to ' + t)
# Article.objects.filter(pk=instance.pk).update(title=t)

# Deletes associated files when object is deleted
@receiver(post_delete, sender=Article)
def delete_html_file_on_delete(sender, instance, **kwargs):
if instance.html_file:
if os.path.isfile(instance.html_file.path):
os.remove(instance.html_file.path)

@receiver(pre_save, sender=Article)
def delete_html_file_on_change(sender, instance, **kwargs):
if not instance.pk:
return False

try:
old_file = Article.objects.get(pk=instance.pk).html_file
except Article.DoesNotExist:
return False

new_file = instance.html_file
if old_file and not old_file == new_file:
if os.path.isfile(old_file.path):
os.remove(old_file.path)
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
{% block content %}
<h2>{{ article }}</h2>
{% if perms.sp_api.change_article %}
<a class="btn btn-warning btn-sm" href="{% url 'sp_app:change_article' article.pk %}">
<a class="btn btn-warning btn-sm" href="{% url 'article:edit' article.pk %}">
<i class="fa fa-pencil-square-o" aria-hidden="true"></i> Edit
</a>
{% endif %}
Expand All @@ -34,7 +34,7 @@ <h2>{{ article }}</h2>
<dt class="col-sm-3">Mots-clés</dt>
<dd class="col-sm-9">
{% for keyword in article.keywords.all %}
<a href="{% url 'sp_app:display_keyword' keyword.pk %}" class="badge badge-primary">
<a href="{% url 'spkeyword:display' keyword.pk %}" class="badge badge-primary">
{{ keyword.name }}
</a>
{% endfor %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ <h4 class="card-title">{{ article }}</a></h4>
<span class="badge badge-light">{{ kw }}</span>
{% endfor %}
</p>
<a href="{% url 'sp_app:display_article' article.pk %}" class="card-link">Read more</a>
<a href="{% url 'article:display' article.pk %}" class="card-link">Read more</a>
<span class="card-link">ID {{ article.pk }}</span>
</div></div>
{% endfor %}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{% extends 'core/base.html' %}

{% block content %}
{% include 'articles/list.html' %}
{% include 'list.html' %}
{% endblock %}
3 changes: 3 additions & 0 deletions drf_sp_hub/article/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.test import TestCase

# Create your tests here.
16 changes: 16 additions & 0 deletions drf_sp_hub/article/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from django.conf.urls import url, include

from .views import ArticleList, ArticleAdd, ArticleDetail, ArticleEdit

app_name = 'article'

article_patterns = [
url(r'^$', ArticleList.as_view(), name='list'),
url(r'^new$', ArticleAdd.as_view(), name='add'),
url(r'^(?P<pk>.+)/$', ArticleDetail.as_view(), name='display'),
url(r'^(?P<pk>.+)/edit$', ArticleEdit.as_view(), name='edit'),
]

urlpatterns = [
url(r'^articles/', include(article_patterns)),
]
46 changes: 46 additions & 0 deletions drf_sp_hub/article/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from django.shortcuts import render
from django.views.generic import ListView, DetailView, CreateView, UpdateView

from .models import Article
from .forms import ArticleForm

from lxml import etree

class ArticleList(ListView):
model = Article
context_object_name = 'articles'
template_name = 'list_page.html'

class ArticleDetail(DetailView):
model = Article
template_name = 'display.html'

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)

if self.object.html_file:
# Init HTML parser
parser = etree.HTMLParser()
tree = etree.parse(self.object.html_file, parser)

extra_head = tree.xpath("//head/meta")
context['extra_head'] = ''
for elm in extra_head:
context['extra_head'] += etree.tostring(elm).decode()

body_elem = tree.xpath("//body/div[@class='article']")
if(body_elem):
context['html_document'] = etree.tostring(body_elem[0]).decode()
else:
context['html_document'] = 'No content'
return context

class ArticleEdit(UpdateView):
model = Article
form_class = ArticleForm
template_name = 'edit.html'

class ArticleAdd(CreateView):
model = Article
form_class = ArticleForm
template_name = 'edit.html'
4 changes: 3 additions & 1 deletion drf_sp_hub/sp_api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

from rest_framework import serializers
from django.contrib.auth.models import User
from sp_app.models import Article, Conversation, SPKeyword, SPCategory
from article.models import Article
from sp_app.models import Conversation
from spkeyword.models import SPKeyword, SPCategory


class ArticleSerializer(serializers.HyperlinkedModelSerializer):
Expand Down
5 changes: 4 additions & 1 deletion drf_sp_hub/sp_api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@

from django.contrib.auth import get_user_model

from sp_app.models import Article, Conversation, SPKeyword, SPCategory
from article.models import Article
from sp_app.models import Conversation
from spkeyword.models import SPKeyword, SPCategory

from .serializers import ArticleSerializer, ConversationSerializer
from .serializers import SPKeywordSerializer, SPCategorySerializer
from .serializers import UserSerializer
Expand Down
17 changes: 1 addition & 16 deletions drf_sp_hub/sp_app/admin.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,5 @@
from django.contrib import admin

from .models import Article, Conversation, SPKeyword, SPCategory

class ArticleInline(admin.TabularInline):
model = Article.keywords.through

class SPKeywordAdmin(admin.ModelAdmin):
list_display = ('name', 'category', 'is_editor', 'aligned', 'language', 'is_translation')
inlines = (ArticleInline, )

class ArticleAdmin(admin.ModelAdmin):
list_display = ('title', 'html_file', 'pk', 'id_senspublic')

class SPCategoryAdmin(admin.ModelAdmin):
list_display = ('name', 'pk')
from .models import Conversation

admin.site.register(Conversation)
admin.site.register(Article, ArticleAdmin)
admin.site.register(SPKeyword, SPKeywordAdmin)
26 changes: 1 addition & 25 deletions drf_sp_hub/sp_app/forms.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,6 @@
from django import forms
from datetimewidget.widgets import DateTimeWidget

from .models import Article, Conversation, SPKeyword, SPCategory

class ArticleForm(forms.ModelForm):
class Meta:
model = Article
fields = [ 'title', 'html_file', 'pdf_file', 'keywords', 'type_article', 'published_on', 'published' ]
widgets = {
'keywords': forms.SelectMultiple(attrs={'class': 'select-multi-keywords, form-control'}),
'published_on': DateTimeWidget(attrs={'id':"yourdatetimeid"}, usel10n = True),
}

class SPKeywordForm(forms.ModelForm):
class Meta:
model = SPKeyword
fields = [ 'name', 'language', 'data', 'aligned', 'is_editor', 'is_translation']
hidden_fields = [ 'data' ]
widgets = {
'is_translation': forms.Select(attrs={'class': 'select-multi-keywords, form-control'})
}

class SPCategoryForm(forms.ModelForm):
class Meta:
model = SPCategory
fields = [ 'name' ]
from .models import Conversation

class ConversationForm(forms.ModelForm):
class Meta:
Expand Down
Loading

0 comments on commit a1fed27

Please sign in to comment.