#!/usr/bin/env python3
# -*- coding: utf-8 -*-

#créé par Pierre, Danrun

import os, re
from bs4 import BeautifulSoup


#fonction pour nettoyage
def nettoyage(chaine):
	nvl_chaine = re.sub(r'<.*?>', '', chaine)
	if nvl_chaine and not nvl_chaine.endswith('.'):
		nvl_chaine += '.'
	return nvl_chaine


#dictionnaire qui permet de gérer les catégories, le compteur des archives, et les doublons en fonction des noms de fichier
#structure: 'nom_fichier': ['catégorie', compteur, 'set_doublons', 0/objet wrapper xml, 0/objet wrapper txt]

cat_name = {
	'0,2-3236,1-0,0.xml': ['actualite-medias', 0, 0, 0, 0],
	'0,2-3234,1-0,0.xml': ['economie', 0, 0, 0, 0],
	'0,2-3210,1-0,0.xml': ['international', 0, 0, 0, 0],
	'0,57-0,64-823353,0.xml': ['politique', 0, 0, 0, 0],
	'0,2-3242,1-0,0.xml': ['sport', 0, 0, 0, 0],
	'0,2-3238,1-0,0.xml': ['vous', 0, 0, 0, 0],
	'0,2-3476,1-0,0.xml': ['cinema', 0, 0, 0, 0],
	'0,2-3214,1-0,0.xml': ['europe', 0, 0, 0, 0],
	'0,2-3260,1-0,0.xml': ['livres', 0, 0, 0, 0],
	'env_sciences.xml': ['sciences', 0, 0, 0, 0],
	'0,2-651865,1-0,0.xml': ['technologies', 0, 0, 0, 0],
	'0,2-3546,1-0,0.xml': ['voyage', 0, 0, 0, 0],
	'0,2-3246,1-0,0.xml': ['culture', 0, 0, 0, 0],
	'0,2-3232,1-0,0.xml': ['idees', 0, 0, 0, 0],
	'0,2-3244,1-0,0.xml': ['planete', 0, 0, 0, 0],
	'0,2-3224,1-0,0.xml': ['societe', 0, 0, 0, 0],
	'0,2-3208,1-0,0.xml': ['une', 0, 0, 0, 0],
}


###############################################################################################################################
'''
cette partie (facultative) permet de rendre le programme plus 'pérenne'
il permet de mettre le dictionnaire à jour en fonction du contenu de nos fichiers
ainsi nous pouvons ajouter quelques flux rss et relancer le programme, les doublons et les compteurs seront gérés correctement
'''
if os.path.exists("./SORTIE_V8") :
	for cat in os.listdir('./SORTIE_V8') :
		for ele in cat_name.values() :
			if ele[0] == cat :
				for rep, srep, fichier in os.walk('./SORTIE_V8/' + cat):
					with open('./SORTIE_V8/' + cat + '/' + fichier[1] ,'r',encoding = 'UTF-8', newline = '\n') as fichierxml :
						contenu = fichierxml.read()
						title_list = re.findall('<title>.*?</title>', contenu)
						nbarchive = len(title_list)
						titles = set(i for i in title_list)
						ele[1], ele[2] = nbarchive, titles

###############################################################################################################################

#demande les catégories à l'utilisateur
for i in cat_name.values():
	print(i[0])

demande = input('Indiquez une ou plusieurs catégories (séparées par espace)\n')

cat_demande = re.findall(r'[\w-]+', demande.lower())

#dico pour renommer les mois en lettre si ce n'est pas le cas
months = {
	'Jan': '01',
	'Feb': '02',
	'Mar': '03',
	'Apr': '04',
	'May': '05',
	'Jun': '06',
	'Jul': '07',
	'Aug': '08',
	'Sep': '09',
	'Oct': '10',
	'Nov': '11',
	'Dec': '12',
}
'''
#renommer les mois en nombre latin pour traiter dans l'ordre 
for dir in os.listdir('./2018'):
	try:
		despath = './2018/' + months[dir]
		dirpath = './2018/' + dir
		os.rename(dirpath, despath)
	except:
		pass
'''
#génération de l'arborescence pour parcourir tous les fichiers et tous les sous-dossiers d'un dossier
for root, dirs, files in os.walk('./2018'):
	for name in files :
		if name in cat_name and cat_name[name][0] in cat_demande: #on exclut les fichiers non pertinents ex : fil.*.xml et on traite seulement les catégories demandées

			#on crée les chemins de fichier
			cat = cat_name[name][0]
			filename = os.path.join(root, name)

			#extraction de la date de publication depuis le chemin du fichier
			pubdate_list = re.findall('\d+', root)
			pubdate = '-'.join(pubdate_list[:3])

			#contrôle progrès de traitement
			print(filename + ' : ' + cat)

			#si aucun dossier ne correspond à la catégorie demandée alors on le crée avec ses fichiers xml et txt, en les ouvrant en mode w (création et écriture, écrasement du contenu de l'ancien fichier si ce dernier existe déjà)
			try:
				os.makedirs("./SORTIE_V8/" + cat)
				xmltmp = open('./SORTIE_V8/' + cat + '/' + cat + '.xml','w', encoding = 'UTF-8', newline = '\n')
				txttmp = open('./SORTIE_V8/' + cat + '/' + cat + '.txt','w', encoding = 'UTF-8', newline = '\n')
				xmltmp.write('<?xml version="1.0" encoding="UTF8"?>\n<file>\n</file>')

			#si les fichiers existent déjà, on les ouvre en mode r+ (lecture + écriture sans écrasement)
			except:
				xmltmp = open('./SORTIE_V8/' + cat + '/' + cat + '.xml','r+', encoding = 'UTF-8', newline = '\n')
				txttmp = open('./SORTIE_V8/' + cat + '/' + cat + '.txt','r+', encoding = 'UTF-8', newline = '\n')

			#on crée un set pour gérer les doublons
			cat_name[name][2] = set()

			#on met les deux objet fichier dans l'entrée correspondante, remplaçant le 0
			cat_name[name][3] = xmltmp
			cat_name[name][4] = txttmp

			cat, counter, titles, sortiexml, sortietxt = cat_name[name]

			#ouverture d'un fichier
			with open(filename, 'rb') as fichier :

				#utilisation du parser xml
				soup = BeautifulSoup(fichier, 'lxml-xml')

				#on récupère le contenu des items
				items = soup.find_all('item')

				for item in items:

					#on compte le nombre d'élément dans le set
					prev_len = len(titles)

					#gestion des doublons avec set
					titles.add(str(item.title))

					#s'il s'agit d'un élément doublon, la fonction add n'a pas d'effet, donc le nombre d'éléments ne change pas; sinon on écrit le titre et la description(s'il y en a une) dans le fichier ouvert précédemment
					if len(titles) != prev_len:
						name_title = nettoyage(str(item.title.string))
						sortiexml.seek(sortiexml.seek(0,2) - 7)
						sortiexml.write('<archive = ' + str(counter) + '>\n<title>' + name_title + "</title>\n")
						sortietxt.seek(0,2)
						sortietxt.write(name_title + '\n')
						counter += 1

						if item.description and item.description.string :
							name_description = nettoyage(str(item.description.string))
							sortiexml.write('<description>' + name_description + '</description>\n')
							sortietxt.write(name_description + '\n\n')
						else:
							sortietxt.write('\n')

						sortiexml.write('<pubDate>' + pubdate + '</pubDate>' + "\n</archive>\n</file>")

			cat_name[name] = [cat, counter, titles, sortiexml, sortietxt] #on met le dictionnaire à jour

#fermeture des fichiers
for for_sortiexml in cat_name.values():
	if type(for_sortiexml[3]) != int:
		for_sortiexml[3].close()
		for_sortiexml[4].close()
