diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..261ac18 --- /dev/null +++ b/Gemfile @@ -0,0 +1,5 @@ +source 'https://rubygems.org' +gem 'daemons' +gem 'httparty' +gem 'addressable' +gem 'mediawiki_api' diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..e449454 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,45 @@ +GEM + remote: https://rubygems.org/ + specs: + addressable (2.7.0) + public_suffix (>= 2.0.2, < 5.0) + daemons (1.3.1) + domain_name (0.5.20190701) + unf (>= 0.0.5, < 1.0.0) + faraday (0.17.3) + multipart-post (>= 1.2, < 3) + faraday-cookie_jar (0.0.6) + faraday (>= 0.7.4) + http-cookie (~> 1.0.0) + faraday_middleware (0.14.0) + faraday (>= 0.7.4, < 1.0) + http-cookie (1.0.3) + domain_name (~> 0.5) + httparty (0.18.1) + mime-types (~> 3.0) + multi_xml (>= 0.5.2) + mediawiki_api (0.7.1) + faraday (~> 0.9, >= 0.9.0) + faraday-cookie_jar (~> 0.0, >= 0.0.6) + faraday_middleware (~> 0.10, >= 0.10.0) + mime-types (3.3.1) + mime-types-data (~> 3.2015) + mime-types-data (3.2020.0512) + multi_xml (0.6.0) + multipart-post (2.1.1) + public_suffix (4.0.5) + unf (0.1.4) + unf_ext + unf_ext (0.0.7.7) + +PLATFORMS + ruby + +DEPENDENCIES + addressable + daemons + httparty + mediawiki_api + +BUNDLED WITH + 2.0.2 diff --git a/README.md b/README.md new file mode 100644 index 0000000..3a84f9a --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +# Catimporter +Importa una categoria (con relative sottocategorie) da una wiki all'altra. +## Prerequisiti +Avere installato Ruby e [bundler](https://bundler.io), dare `bundle install`. Tutte le dipendenze saranno così installate. +## Configurazione +Eseguite lo script chiamato `process.rb` (per esempio, col comando `$ ruby process.rb`) vi verranno richiesti alcuni parametri fondamentali che verranno salvati in un file chiamato .config e ripresi automaticamente alle successive esecuzioni. +## Daemonizzare +Per rendere lo script in continua esecuzione (facendolo diventare un daemon) e controllarlo, è possibile usare i seguenti comandi ereditati dalla gem [daemons](https://github.com/thuehlinger/daemons): +``` +$ ruby bot.rb start + (process.rb is now running in the background) +$ ruby bot.rb restart + (...) +$ ruby bot.rb stop +``` diff --git a/bot.rb b/bot.rb new file mode 100644 index 0000000..8feafed --- /dev/null +++ b/bot.rb @@ -0,0 +1,3 @@ +require 'daemons' + +Daemons.run('trashop.rb') diff --git a/process.rb b/process.rb new file mode 100644 index 0000000..1bf5c84 --- /dev/null +++ b/process.rb @@ -0,0 +1,109 @@ +require 'HTTParty' +require 'addressable' +require 'mediawiki_api' +# Legge le credenziali e la wiki di destinazione +if !File.exist? '.config' + puts 'Inserisci username:' + print '> ' + username = gets.chomp + puts 'Inserisci password:' + print '> ' + password = gets.chomp + puts 'Inserisci indirizzo API della wiki di provenienza (nella forma https://it.wikipedia.org/w/api.php)' + print '> ' + fromwiki = gets.chomp + puts 'Inserisci indirizzo API della wiki di destinazione (nella forma https://it.wikipedia.org/w/api.php)' + print '> ' + importwiki = gets.chomp + puts "Inserisci il prefisso interwiki della wiki di provenienza sulla wiki di destinazione, avendo cura di verificare che l'importazione sia abilitata per quel prefisso" + print '> ' + interwikiprefix = gets.chomp + puts "Inserisci la categoria che contiene le pagine da importare (l'importazione è ricorsiva)" + print '> ' + importcat = gets.chomp + File.open(".config", "w") do |file| + file.puts username + file.puts password + file.puts fromwiki + file.puts importwiki + file.puts interwikiprefix + file.puts importcat + end +end +userdata = File.open(".config", "r").to_a +fromwiki = userdata[2] +importwiki = userdata[3] +importcat = userdata[5] + +# Funzione per ottenere i membri della categoria +def getcatmembers(cat) + pagelist = HTTParty.get("#{fromwiki}?action=query&list=categorymembers&cmtitle=#{cat}&format=json&cmlimit=max", uri_adapter: Addressable::URI).to_a + unless pagelist.empty? + if pagelist[2].nil? + pagelist = pagelist[1][1]['categorymembers'] + else + cmcontinue = pagelist[1][1]['cmcontinue'] + continue = pagelist[1][1]['continue'] + pagelist = pagelist[2][1]['categorymembers'] + end + + unless pagelist.nil? + while continue == '-||' + puts 'Ottengo la continuazione della categoria...' + new_pagelist = HTTParty.get(fromwiki, query: {action: :query, list: :categorymembers, cmtitle: cat, cmlimit: 500, cmdir: :newer, cmcontinue: cmcontinue, format: :json }, uri_adapter: Addressable::URI).to_a + unless new_pagelist.nil? + if new_pagelist[2].nil? + new_pagelist = new_pagelist[1][1]['categorymembers'] + continue = false + @noph = true + else + cmcontinue = new_pagelist[1][1]['cmcontinue'] + continue = new_pagelist[1][1]['continue'] + new_pagelist = new_pagelist[2][1]['categorymembers'] + end + unless new_pagelist.nil? + puts 'Sommo le liste di foto...' + pagelist = pagelist += new_pagelist + end + end + end + end + return pagelist + end +end + +# recupera la lista delle categorie con pagine da cancellare +catlist = HTTParty.get("#{fromwiki}?action=query&list=categorymembers&cmtitle=#{importcat}&format=json&cmlimit=max", uri_adapter: Addressable::URI).to_a[2][1]['categorymembers'] +catlist.reject! { |cat| cat["ns"] != 14 } +totalcontain = [] +catlist.each do |cat| + getcatmembers(cat["title"]).each do |page| + totalcontain.push(page) + end +end + +# Verifica e rientra nelle sottocategorie e nelle eventuali categorie più sommerse +count = 0 +totalcontain.each { |tc| count += 1 if tc["ns"] == 14} +while(count > 0) + totalcontain.each do |tc| + if tc["ns"] == 14 + getcatmembers(tc["title"]).each do |page| + totalcontain.push(page) + end + totalcontain.delete(tc) + end + end + count = 0 + totalcontain.each { |tc| count += 1 if tc["ns"] == 14} +end + +# Rimuove le voci già sul wiki dall'array +totalcontain.reject! { |page| HTTParty.get(importwiki + '?action=query&list=search&srsearch="' + page["title"] + '"&format=json&srlimit=max&srwhat=title', uri_adapter: Addressable::URI).to_a[2][1]["searchinfo"]["totalhits"] > 0} + +# Importa la voce nel wiki, funziona solo se c'è un interwiki a Wikipedia in Italiano con w, modificabile secondo necessità +client = MediawikiApi::Client.new importwiki +client.log_in "#{userdata[0]}", "#{userdata[1]}" +totalcontain.each do |page| + client.action(:import, summary: "Importazione della pagina #{page["title"]} #ImportCatBot", interwikiprefix: userdata[4], interwikipage: page["title"], fullhistory: true, template: true) +end \ No newline at end of file