djangoldp-ds4go 1.0.0__py3-none-any.whl → 1.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- djangoldp_ds4go/__init__.py +1 -1
- djangoldp_ds4go/management/__init__.py +0 -0
- djangoldp_ds4go/management/commands/__init__.py +0 -0
- djangoldp_ds4go/management/commands/import_rss.py +126 -0
- djangoldp_ds4go/models/category.py +1 -0
- djangoldp_ds4go/models/fact.py +2 -1
- {djangoldp_ds4go-1.0.0.dist-info → djangoldp_ds4go-1.0.1.dist-info}/METADATA +1 -1
- {djangoldp_ds4go-1.0.0.dist-info → djangoldp_ds4go-1.0.1.dist-info}/RECORD +10 -7
- {djangoldp_ds4go-1.0.0.dist-info → djangoldp_ds4go-1.0.1.dist-info}/WHEEL +0 -0
- {djangoldp_ds4go-1.0.0.dist-info → djangoldp_ds4go-1.0.1.dist-info}/top_level.txt +0 -0
djangoldp_ds4go/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = '1.0.
|
|
1
|
+
__version__ = '1.0.1'
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import json
|
|
2
|
+
|
|
3
|
+
from defusedxml.ElementTree import parse
|
|
4
|
+
from django.core.management.base import BaseCommand
|
|
5
|
+
|
|
6
|
+
from djangoldp_ds4go.models import Category, Fact, Media
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Command(BaseCommand):
|
|
10
|
+
help = "Import facts from RSS file"
|
|
11
|
+
|
|
12
|
+
def add_arguments(self, parser):
|
|
13
|
+
parser.add_argument("--rss_file", type=str, help="Path to the RSS file")
|
|
14
|
+
|
|
15
|
+
def handle(self, *args, **options):
|
|
16
|
+
rss_file = options["rss_file"]
|
|
17
|
+
tree = parse(rss_file)
|
|
18
|
+
root = tree.getroot()
|
|
19
|
+
ns = {
|
|
20
|
+
"schema": "https://schema.org/",
|
|
21
|
+
"media": "http://search.yahoo.com/mrss/",
|
|
22
|
+
"content": "http://purl.org/rss/1.0/modules/content/",
|
|
23
|
+
}
|
|
24
|
+
channel = root.find("channel")
|
|
25
|
+
language_elem = channel.find("language")
|
|
26
|
+
language = language_elem.text if language_elem is not None else "fr"
|
|
27
|
+
|
|
28
|
+
for item in channel.findall("item"):
|
|
29
|
+
guid = item.find("guid").text
|
|
30
|
+
existing_fact = Fact.objects.filter(rss_guid=guid).first()
|
|
31
|
+
title = item.find("title").text
|
|
32
|
+
link = item.find("link").text
|
|
33
|
+
review_elem = item.find("schema:review", ns)
|
|
34
|
+
|
|
35
|
+
try:
|
|
36
|
+
review = json.loads(review_elem.text) if review_elem is not None else {}
|
|
37
|
+
except json.JSONDecodeError:
|
|
38
|
+
review = {}
|
|
39
|
+
self.stderr.write(self.style.WARNING("Failed to parse review for item with guid %s. Ignoring." % (guid)))
|
|
40
|
+
|
|
41
|
+
description = item.find("description").text
|
|
42
|
+
content_elem = item.find("content:encoded", ns)
|
|
43
|
+
content = content_elem.text if content_elem is not None else ""
|
|
44
|
+
author = item.find("author").text if item.find("author") is not None else ""
|
|
45
|
+
enclosure_url = None
|
|
46
|
+
enclosure = item.find("enclosure")
|
|
47
|
+
|
|
48
|
+
if enclosure is not None:
|
|
49
|
+
enclosure_url = enclosure.get("url")
|
|
50
|
+
|
|
51
|
+
if existing_fact:
|
|
52
|
+
fact = existing_fact
|
|
53
|
+
self.stdout.write(f"Updating existing fact with guid {guid}")
|
|
54
|
+
else:
|
|
55
|
+
fact = Fact.objects.create(
|
|
56
|
+
rss_guid=guid,
|
|
57
|
+
link=link,
|
|
58
|
+
review=review,
|
|
59
|
+
)
|
|
60
|
+
self.stdout.write(f"Creating new fact: {title}")
|
|
61
|
+
|
|
62
|
+
# Set translated fields
|
|
63
|
+
setattr(fact, f"name_{language}", title)
|
|
64
|
+
setattr(fact, f"description_{language}", description)
|
|
65
|
+
setattr(fact, f"content_{language}", content)
|
|
66
|
+
setattr(fact, f"author_{language}", author)
|
|
67
|
+
|
|
68
|
+
if enclosure_url:
|
|
69
|
+
setattr(fact, f"enclosure_{language}", enclosure_url)
|
|
70
|
+
|
|
71
|
+
fact.save()
|
|
72
|
+
|
|
73
|
+
# Categories
|
|
74
|
+
categories = item.findall("category")
|
|
75
|
+
for cat_elem in categories:
|
|
76
|
+
cat_name = cat_elem.text
|
|
77
|
+
category = self.get_or_create_category(cat_name, language)
|
|
78
|
+
fact.categories.add(category)
|
|
79
|
+
|
|
80
|
+
# Medias
|
|
81
|
+
for media_elem in item.findall("media:content", ns):
|
|
82
|
+
url = media_elem.get("url")
|
|
83
|
+
file_size = int(media_elem.get("fileSize", 0))
|
|
84
|
+
width = int(media_elem.get("width", 0))
|
|
85
|
+
height = int(media_elem.get("height", 0))
|
|
86
|
+
file_type = media_elem.get("type")
|
|
87
|
+
desc = media_elem.find("media:description", ns)
|
|
88
|
+
description = desc.text if desc is not None else ""
|
|
89
|
+
existing_media = Media.objects.filter(
|
|
90
|
+
url=url, related_fact=fact
|
|
91
|
+
).first()
|
|
92
|
+
|
|
93
|
+
if existing_media:
|
|
94
|
+
setattr(existing_media, f"description_{language}", description)
|
|
95
|
+
existing_media.save()
|
|
96
|
+
else:
|
|
97
|
+
media = Media.objects.create(
|
|
98
|
+
url=url,
|
|
99
|
+
file_size=file_size,
|
|
100
|
+
width=width,
|
|
101
|
+
height=height,
|
|
102
|
+
file_type=file_type,
|
|
103
|
+
related_fact=fact,
|
|
104
|
+
)
|
|
105
|
+
setattr(media, f"description_{language}", description)
|
|
106
|
+
media.save()
|
|
107
|
+
|
|
108
|
+
self.stdout.write(f"Processed fact: {title}")
|
|
109
|
+
|
|
110
|
+
def get_or_create_category(self, cat_name, language):
|
|
111
|
+
parts = cat_name.split("/")
|
|
112
|
+
current_parent = None
|
|
113
|
+
|
|
114
|
+
for part in parts:
|
|
115
|
+
part = part.strip()
|
|
116
|
+
category, created = Category.objects.get_or_create(
|
|
117
|
+
name=part,
|
|
118
|
+
parent_category=current_parent,
|
|
119
|
+
)
|
|
120
|
+
# FIXME: I don't know how to handle i18n here as these are strings: "Media Topic" could be "Totoro" in another lang?
|
|
121
|
+
# if created or not getattr(category, f"name_{language}", None):
|
|
122
|
+
# setattr(category, f"name_{language}", part)
|
|
123
|
+
# category.save()
|
|
124
|
+
current_parent = category
|
|
125
|
+
|
|
126
|
+
return current_parent
|
|
@@ -14,6 +14,7 @@ class Category(baseNamedModel):
|
|
|
14
14
|
class Meta(baseNamedModel.Meta):
|
|
15
15
|
verbose_name = _("Category")
|
|
16
16
|
verbose_name_plural = _("Categories")
|
|
17
|
+
container_path = "categories"
|
|
17
18
|
|
|
18
19
|
rdf_type = "ds4go:Category"
|
|
19
20
|
serializer_fields = baseNamedModel.Meta.serializer_fields + [
|
djangoldp_ds4go/models/fact.py
CHANGED
|
@@ -26,6 +26,7 @@ class Fact(baseNamedModel):
|
|
|
26
26
|
enclosure = fields.LDPUrlField(blank=True, null=True, verbose_name=_("Enclosure"))
|
|
27
27
|
|
|
28
28
|
class Meta(baseNamedModel.Meta):
|
|
29
|
+
depth = 1
|
|
29
30
|
verbose_name = _("Fact")
|
|
30
31
|
verbose_name_plural = _("Facts")
|
|
31
32
|
|
|
@@ -41,6 +42,6 @@ class Fact(baseNamedModel):
|
|
|
41
42
|
"review",
|
|
42
43
|
]
|
|
43
44
|
|
|
44
|
-
nested_fields = baseNamedModel.Meta.nested_fields + ["medias"]
|
|
45
|
+
nested_fields = baseNamedModel.Meta.nested_fields + ["categories", "medias"]
|
|
45
46
|
|
|
46
47
|
view_set = I18nLDPViewSet
|
|
@@ -1,17 +1,20 @@
|
|
|
1
|
-
djangoldp_ds4go/__init__.py,sha256=
|
|
1
|
+
djangoldp_ds4go/__init__.py,sha256=3KXfAcA5rzzQXMtfwpHphgbJNZdA0XWaW96kdWVSZJw,22
|
|
2
2
|
djangoldp_ds4go/admin.py,sha256=1hAS44RxwBQcsTmH0OezB1J3XYdqi-AVRixZGWpDrkc,696
|
|
3
3
|
djangoldp_ds4go/apps.py,sha256=ILJSj_OE1GFMh7Fk5EKiaq14SgQHwJvorF__7JLXuH0,104
|
|
4
4
|
djangoldp_ds4go/translation.py,sha256=LhOAiSDIujlghrWJWsZhJ03qlg1yn0eD3b0g7x03t30,465
|
|
5
|
+
djangoldp_ds4go/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
djangoldp_ds4go/management/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
+
djangoldp_ds4go/management/commands/import_rss.py,sha256=Tb96lWEFOtCjV1OdlOhOPZkNCfTt3TTF2IR3RF6VU04,4963
|
|
5
8
|
djangoldp_ds4go/migrations/0001_initial.py,sha256=x2FVAd14EKozCrYX1u3LkjQ8o5zwqR9af4OMYrHvGCs,11411
|
|
6
9
|
djangoldp_ds4go/migrations/0002_djangoldp_i18n.py,sha256=YISp85aSIX5gKQ2fKWXteDFP20U3n37G1ujcizR8LTU,5107
|
|
7
10
|
djangoldp_ds4go/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
11
|
djangoldp_ds4go/models/__base_model.py,sha256=R967mGmZ9NQpNPRXENCBCcPwR94c6EfliQ8IvbrF8is,844
|
|
9
12
|
djangoldp_ds4go/models/__base_named_model.py,sha256=k__648DawntqwZz_BgcbSQ42JFcUcS042F-Z90YrlZQ,523
|
|
10
13
|
djangoldp_ds4go/models/__init__.py,sha256=0dbHkGh9xLTVNQzZJs62QgqpBXhTMIqHBjwlUseEe18,127
|
|
11
|
-
djangoldp_ds4go/models/category.py,sha256=
|
|
12
|
-
djangoldp_ds4go/models/fact.py,sha256=
|
|
14
|
+
djangoldp_ds4go/models/category.py,sha256=wJxPW6q5ezb14GuVBh2rt5UdkCQ_wqqs4XhOMSqB4l4,719
|
|
15
|
+
djangoldp_ds4go/models/fact.py,sha256=2NNrHnf0ZvCIEHIGlW9h64L2q6gmSmASHB63DoRw-Vw,1616
|
|
13
16
|
djangoldp_ds4go/models/media.py,sha256=quGqgjRm9rhoS3ZTSuVDxf3Te_fi6xYakOKmN0UsvQs,1442
|
|
14
|
-
djangoldp_ds4go-1.0.
|
|
15
|
-
djangoldp_ds4go-1.0.
|
|
16
|
-
djangoldp_ds4go-1.0.
|
|
17
|
-
djangoldp_ds4go-1.0.
|
|
17
|
+
djangoldp_ds4go-1.0.1.dist-info/METADATA,sha256=phbUuTDHab5lLH8M87zj69J8y56o-LYLoRSAh00zd9U,482
|
|
18
|
+
djangoldp_ds4go-1.0.1.dist-info/WHEEL,sha256=SmOxYU7pzNKBqASvQJ7DjX3XGUF92lrGhMb3R6_iiqI,91
|
|
19
|
+
djangoldp_ds4go-1.0.1.dist-info/top_level.txt,sha256=EZCxKGM892iifGOQnzWhprBIbSp05371s-H6QLsRf7s,16
|
|
20
|
+
djangoldp_ds4go-1.0.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|