pcards/cards/management/commands/gcstar_import.py

161 lines
4.6 KiB
Python

#coding=utf-8
from django.core.management.base import BaseCommand, CommandError
from django.core.files import File
from xcards.cards.models import *
import os
from lxml import etree
class Command(BaseCommand):
args = '<filepath to open>'
help = 'Import data from an xml file generated by gc-star'
def handle(self, *args, **options):
if args is None or len(args) == 0:
raise Exception("Aucun fichier n'a été fourni en argument.")
l = self.fetch_gclist(args[0])
for item in l:
self.insert(item)
self.stdout.write('Successfully import information from data file\n')
def fetch_gclist(self, filepath):
"""
Ouvre un fichier GCStar structuré de la manière suivante:
<collection...>
<item
gcsfield1="France" => pays
gcsfield2="1" => avec ou sans puce
gcsfield3="france/Alimentation/Gourmandises/milka 50.jpg" => image
gcsfield4="Gourmandises" => souscatégorie
gcsfield5="50" => unités
gcsfield6="Milka Lila Pause" => label
gcsfield7="02/1996" => année d'émission
gcsfield8="" => date d'expiration
gcsfield9="B61013013" => pas utile
gcsfield10="1000000" => tirage
gcsfield11="Alimentation " => catégorie
gcsautoid="19" => nafout
>
</collection>
"""
if not os.path.exists(filepath):
raise IOError("Le fichier fourni en paramètre n'existe pas.")
element = etree.parse(filepath)
items = element.xpath('//collection/item')
my_list = list()
for item in items:
attrs = item.attrib
i = GCItem()
i.country = attrs.get('gcsfield1')
i.with_chip = attrs.get('gcsfield2')
i.image_path = self._get_absfilepath(os.path.dirname(filepath), attrs.get('gcsfield3'))
i.subcategory = attrs.get('gcsfield4')
i.units = attrs.get('gcsfield5')
i.label = attrs.get('gcsfield6')
i.emissionDate = attrs.get('gcsfield7')
i.expirationDate = attrs.get('gcsfield8')
i.numberOfCopies = attrs.get('gcsfield10')
i.category = attrs.get('gcsfield11')
i.gcsid = attrs.get('gcsautoid')
my_list.append(i)
return my_list
def _get_absfilepath(self, folderpath, filepath):
"""
En paramètres:
- le dossier dans lequel se trouve le fichier xml
- le fichier à trouver
Si le chemin référence déjà un chemin absolu, on le retourne simplement,
sinon, on combine les deux (le dossier et le chemin vers le fichier) et on retourne le résultat
s'il existe. Note: dans certains cas, GCStar stocke ses fichiers dans un dossier 'collection_images'.
Si le fichier n'a pas été trouvé, on jette une exception de type IOError.
"""
if filepath.startswith('./'):
filepath = filepath[2:]
possiblePaths = (filepath, os.path.join(folderpath, 'collection_images', filepath),
os.path.join(folderpath, filepath),)
for file in possiblePaths:
if os.path.exists(file):
return os.path.abspath(file)
#raise IOError("Le fichier référencé n'existe pas. Chemins essayés: %s" % (', '.join(possiblePaths)))
self.stdout.write("Le fichier référencé n'existe pas. Chemins essayés: %s" % (', '.join(possiblePaths)))
return None
def insert(self, item):
"""
Insère un item provenant de GCStar dans la base de données.
"""
i = Item()
country, created = Country.objects.get_or_create(label=item.country.strip())
i.country = country
category, created = Category.objects.get_or_create(label=item.category.strip())
i.category = category
subcategory, created = SubCategory.objects.get_or_create(label=item.subcategory.strip())
i.subcategory = subcategory
i.units = item.units
i.label = item.label
i.emissionDate = item.emissionDate
i.expirationDate = item.expirationDate
i.numberOfCopies = item.numberOfCopies
if item.image_path is not None:
i.image.save(os.path.basename(item.image_path), File(open(item.image_path, 'rb')))
i.save()
class GCItem():
"""
i.country = attrs.get('gcsfield1')
i.with_chip = attrs.get('gcsfield2')
i.image_path = attrs.get('gcsfield3')
i.subcategory = attrs.get('gcsfield4')
i.units = attrs.get('gcsfield5')
i.label = attrs.get('gcsfield6')
i.emissionDate = attrs.get('gcsfield7')
i.expirationDate = attrs.get('gcsfield8')
i.numberOfCopies = attrs.get('gcsfield10')
i.category = attrs.get('gcsfield11')
"""
country = None
with_chip = False
image_path = None
subcategory = None
units = None
label = None
emissionDate = None
expirationDate = None
numberOfCopies = None
category = None
gcsid = None
def __str__(self):
return u'%s / %s / %s / %s' % (self.country, self.category, self.subcategory, self.image_path)
def __unicode__(self):
return u'%s / %s / %s / %s' % (self.country, self.category, self.subcategory, self.image_path)