Created
December 30, 2009 09:25
-
-
Save Riduidel/265942 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'yaml' | |
#DUMP_FILE = 'extract_dump_mysql.sql' | |
DUMP_FILE = 'wordpress_wp_20061231_000.sql' | |
DUMP_EXPORT_DIR = "dump" | |
CATEGORIES_STORE = 'categories_files.yaml' | |
# La lecture du fichier a été copiée de http://pleac.sourceforge.net/pleac_ruby/fileaccess.html | |
# Hash associant à leurs ids les catégories, sous forme elles aussi de hash | |
categories = Hash.new | |
def get_parameters(line, text_columns) | |
# Faudrait d'abord réussir à placer un post dans une tableau, pour ensuite traiter les différents arguments. | |
# Pour ça, pas compliqué : je prends dans la ligne le contenu entre la première '(' et la dernière ')' | |
inserted = line[line.index('(')+1 .. line.rindex(')')-1] | |
# Maintenant, on en fait un tableau, en découpant à chaque virgule ... enfin, presque, puisqu'il faut éviter | |
# celles qui sont dans des chaînes, et éviter les limites de chaînes échappées | |
parameters = Array.new | |
text_ended = false | |
text = "" | |
inserted.each(',') do |parameter| | |
parameter.gsub!("\\\'", "\'") | |
parameter.gsub!("\\r", "\r") | |
parameter.gsub!("\\n", "\n") | |
parameter.gsub!("\\t", "\t") | |
# Il y a du gros texte dans les quatrièmes et septièmes colonnes. | |
# Dans ces colonnes, la virgule qui compte est précédée (comme dernier caractère non blanc) | |
# par un ' qui n'est pas échappé | |
if text_columns.include? parameters.size | |
if parameter.size>3 | |
text_ended = parameter[parameter.size-2,1]=="'" && parameter[parameter.size-3,1]!="\\" | |
elsif parameter.size>2 | |
text_ended = parameter[parameter.size-2,1]=="'" | |
end | |
text << parameter | |
if text_ended | |
parameters << text[text.index("'")+1..text.rindex("'")-1].strip | |
text_ended = false | |
text = "" | |
end | |
else | |
if parameter[1..1]=="'" | |
parameters << parameter[2 .. parameter.size-3].strip | |
elsif parameter.index(",")==parameter.size-1 | |
parameters << parameter[0, parameter.size-1].strip | |
else | |
parameters << parameter.strip | |
end | |
end | |
end | |
return parameters | |
end | |
def make_file_from_post(line, categories, categories_files) | |
# Tout ça, c'est juste un parsing de ligne, un peu compliqué, car c'est un statement MySQL. | |
# Est-ce que je ne pourrais pas plutôt le parser comme du SQl et en lire les arguments ? | |
# Ce serait malin. Helas, je n'ai pas trouvé de lib Ruby qui fasse le boulot pour moi. | |
# Donc tout à la main. | |
# Résumons-nous. La table wp_posts est faite comme ça : | |
# 0 `ID` bigint(20) unsigned NOT NULL auto_increment, | |
# 1 `post_author` bigint(20) NOT NULL default '0', | |
# 2 `post_date` datetime NOT NULL default '0000-00-00 00:00:00', | |
# 3 `post_date_gmt` datetime NOT NULL default '0000-00-00 00:00:00', | |
# 4 `post_content` longtext NOT NULL, | |
# 5 `post_title` text NOT NULL, | |
# 6 `post_category` int(4) NOT NULL default '0', | |
# 7 `post_excerpt` text NOT NULL, | |
# 8 `post_status` enum('publish','draft','private','static','object','attachment') NOT NULL default 'publish', | |
# 9 `comment_status` enum('open','closed','registered_only') NOT NULL default 'open', | |
# 10 `ping_status` enum('open','closed') NOT NULL default 'open', | |
# 11 `post_password` varchar(20) NOT NULL default '', | |
# 12 `post_name` varchar(200) NOT NULL default '', | |
# 13 `to_ping` text NOT NULL, | |
# 14 `pinged` text NOT NULL, | |
# 15 `post_modified` datetime NOT NULL default '0000-00-00 00:00:00', | |
# 16 `post_modified_gmt` datetime NOT NULL default '0000-00-00 00:00:00', | |
# 17 `post_content_filtered` text NOT NULL, | |
# 18 `post_parent` bigint(20) NOT NULL default '0', | |
# 19 `guid` varchar(255) NOT NULL default '', | |
# 20 `menu_order` int(11) NOT NULL default '0', | |
# 21 `post_type` varchar(100) NOT NULL default '', | |
# 22 `post_mime_type` varchar(100) NOT NULL default '', | |
# 23 `comment_count` bigint(20) NOT NULL default '0', | |
parameters = get_parameters(line, [4, 7]) | |
# Maintenant, on a de quoi faire un fichier ! | |
# post_content (champ 4) comme contenu | |
# psot_excerpt (7) pour mettre comme résumé (un deuxième bloc de texte) | |
# post_category (6) pour choisir le bon dossier et la catégorie utilisée dans le menu | |
# post_title (5)comme titre | |
# post_date (2)comme date de modif, | |
# post_name comme nom de fichier | |
# on recherche la bonne catégorie | |
category_array = categories.select do |cat_id, cat| | |
cat[6].include? parameters[0] | |
end | |
category = category_array.size>0 ? category_array[0][1] : nil | |
expected_file_name = "" | |
if category==nil | |
expected_file_name = DUMP_EXPORT_DIR+"\\"+"\\"+parameters[12]+".page" | |
else | |
expected_file_name = categories_files[category[2]]+"\\"+parameters[12]+".page" | |
end | |
# le fichier va être créé ou réinitialisé | |
export = File.open(expected_file_name, File::WRONLY|File::TRUNC|File::CREAT) | |
export << "---\n" | |
# Un petit hack pour éviter la création d'une section | |
export << "title: "+parameters[5].to_yaml.gsub("--- ","") | |
# Maintenant, on transforme la vieille date Wordpress en nouvelle date Ruby | |
# Et par convention, on prend la date locale | |
date = DateTime.strptime(parameters[2], "%Y-%m-%d %H:%M:%S") | |
export << "filemdate: "+date.to_yaml.gsub("--- ","") | |
export << "\n---\n" | |
export << parameters[4] | |
# Ca marche pas encore bien ce truc-là. je vais essayer de trouver la feinte ! | |
# if parameters[7]!=nil && parameters[7].size>0 | |
# export << "\n--- excerpt\n" | |
# export << parameters[7] | |
# end | |
puts "written "+expected_file_name | |
end | |
def create_hierarchy expected_dir | |
if !File.directory? expected_dir | |
puts "directory "+expected_dir+" does not exists yet." | |
parts = File.split(File.expand_path(expected_dir)) | |
create_hierarchy parts[0] | |
Dir.mkdir expected_dir | |
end | |
end | |
def create_category_from(line, categories, categories_store) | |
# 0 `cat_ID` bigint(20) NOT NULL auto_increment, | |
# 1 `cat_name` varchar(55) NOT NULL default '', | |
# 2 `category_nicename` varchar(200) NOT NULL default '', faut pas se tromper, en fait, le nicename, c'est celui qu'on peut utiliser dans un nom de fichier | |
# 3 `category_description` longtext NOT NULL, | |
# 4 `category_parent` bigint(20) NOT NULL default '0', | |
# 5 `category_count` bigint(20) NOT NULL default '0', | |
parameters = get_parameters(line, [1, 2, 3]) | |
# faut d'abord mettre la catégorie dans le hash des catégories | |
categories[parameters[0]]=parameters | |
# liste des identifiants de page dans la catégorie. C'est sale, mais ça peut marcher | |
# Le tableau sera à l'indice 6 | |
parameters << [] | |
# Maintenant, on a de quoi faire un fichier ! | |
# post_content (champ 4) comme contenu | |
# psot_excerpt (7) pour mettre comme résumé (un deuxième bloc de texte) | |
# post_title (5)comme titre | |
# post_date (2)comme date de modif, | |
# post_name comme nom de fichier | |
expected_dir = "" | |
if categories_store.has_key?(parameters[2]) | |
expected_dir = categories_store[parameters[2]] | |
else | |
expected_dir = DUMP_EXPORT_DIR+"\\"+parameters[2] | |
categories_store[parameters[2]] = expected_dir | |
end | |
create_hierarchy expected_dir | |
expected_file_name = expected_dir+"\\index.page" | |
# le fichier va être créé ou réinitialisé | |
export = File.open(expected_file_name, File::WRONLY|File::TRUNC|File::CREAT) | |
export << "---\n" | |
# Un petit hack pour éviter la création d'une section | |
export << "title: "+parameters[1].to_yaml.gsub("--- ","") | |
export << "\ninMenu: true" | |
# La catégorie est placée dans le menu de sa catégorie parente | |
# Mais alors ça, je sais pas du tout comment faire | |
export << "\n---\n" | |
export << "h1. "+parameters[1]+"\n\n" | |
export << parameters[3] | |
export << "\n\n{filelist:}" | |
puts "written "+parameters[2] | |
end | |
def link_post_id_to_category(line, categories, categories_files) | |
# 0 `rel_id` bigint(20) NOT NULL auto_increment, | |
# 1 `post_id` bigint(20) NOT NULL default '0', | |
# 2 `category_id` bigint(20) NOT NULL default '0', | |
parameters = get_parameters(line, []) | |
if categories.has_key? parameters[2] | |
categories[parameters[2]][6] << parameters[1] | |
end | |
end | |
def make_file_from_page(line, categories, categories_file) | |
end | |
if File.exist? CATEGORIES_STORE | |
categories_files = YAML.load_file(CATEGORIES_STORE) | |
else | |
categories_files = {} | |
end | |
# An IO object being Enumerable, we can use 'each' directly on it | |
File.open(DUMP_FILE).each do |line| | |
create_category_from(line, categories, categories_files) if line =~ /INSERT INTO `wp_categories`/ | |
link_post_id_to_category(line, categories, categories_files) if line =~ /INSERT INTO `wp_post2cat`/ | |
make_file_from_post(line, categories, categories_files) if line =~ /INSERT INTO `wp_posts`/ | |
make_file_from_page(line, categories, categories_files) if line =~ /INSERT INTO `wp_posts`/ | |
end | |
#puts categories.inspect | |
File.open( CATEGORIES_STORE, File::WRONLY|File::TRUNC|File::CREAT) do |out| | |
YAML.dump( categories_files, out ) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment