Versuchen Sie, den API-Schlüssel von Redmine mit Ruby zu erhalten

Hintergrund

Ich wurde gebeten, den Redmine-API-Schlüssel mit Ruby bei der Arbeit erhalten zu können. Ich habe die Fertigstellung vorerst gesehen, daher werde ich sie anstelle meines Memorandums zusammenfassen.   Der Artikel wurde nur von einem Programmieranfänger im ersten Berufsjahr erstellt, der einen Job als Programmierer bekam, indem er allein studierte, die Suche und das Kopieren wiederholte. Wenn es eine Person gibt, die mir ähnlich ist, hoffe ich, dass dieser Artikel allein ein Erfolg wird.

Methode

Ich habe zuerst danach gesucht, aber die entsprechende Beschreibung nicht gefunden. Unter der Annahme, dass der API-Schlüssel vom persönlichen Einstellungsbildschirm von redmine empfangen und in den Code eingegeben wird, konnte ich keine Möglichkeit finden, den API-Schlüssel programmgesteuert abzurufen. Als Ergebnis der Suche ohne den Zustand von Rubin wurde jedoch der folgende Artikel gefunden.

So erhalten Sie verschiedene Daten aus Redmine JavaScript https://qiita.com/forenoonM/items/7f42701b2ea40353a820

Dieser Artikel beschreibt, wie Sie den API-Schlüssel mit JavaScript abrufen. Grob gesagt ist es eine Methode mit Scraping.

Kratzpraxis

Ich verstehe, kratzen? Peinlicherweise wusste ich nicht einmal, was Kratzen ist. Immerhin bin ich ein Anfänger, der gerade alleine Rubin studiert hat. Also suchte ich nach einer Methode zum Abkratzen mit Rubin und kam an die folgende Stelle.

[In 5 Minuten verstehen] Erklären Sie die Grundlagen des Scrapings mit Ruby! https://www.sejuku.net/blog/13230

Dies ist der auf diese Weise erstellte Code

equire 'open-uri'
require 'nokogiri' #Wird verwendet, um den API-Schlüssel abzurufen
url = "http://192.168.33.11/my/api_key"

charset = nil

html = open(url) do |page|
 charaset = page.charset
 page.read
end

contents = Nokogiri::HTML.parse(html,nil,charset)
apikey = contents.search("div[@class='box']").search('pre')
puts apikey

Nun, wenn ich es tatsächlich bewege, bewegt es sich nicht. Als Ergebnis verschiedener Untersuchungen bemerkte ich, dass es auf dem Anmeldebildschirm aufhörte.

Das heißt, Sie müssen einen Anmeldevorgang erstellen

Anmeldevorgang erstellen

Also bin ich wie immer durch Suchen zu dieser Seite gekommen.

Melden Sie sich mit Mechanize an und kratzen Sie https://qiita.com/katsuyuki/items/1a78360988d96eec1d54

Ich verstehe es vollständig.

agent = Mechanize.new
agent.user_agent = 'Mac Safari'
agent.get("http://#{adress}/my/api_key") do |page|
  response = page.form_with(:action => '/login') do |form|
    formdata = {
       :mail => mail,
       :password => password,
    }
    form.field_with(:name => 'username').value = formdata[:mail]
    form.field_with(:name => 'password').value = formdata[:password]
  end.submit
 end
 url = "http://#{adress}/my/api_key"
 html = agent.get("#{url}").content.toutf8
 contents = Nokogiri::HTML(html, nil, 'utf-8')
 apikey = contents.search("div[@class='box']").search('pre')
 puts apikey

Nur der zusätzliche Teil wurde extrahiert.

Übrigens sagte er zu # {adress}: "Ich teste jetzt lokal, aber danach werde ich es auf der Redmine des Unternehmens und der Redmine des Kunden ausführen."

require 'yaml' #Wird zum Lesen der Konfiguration verwendet

set = YAML.load_file("config.yml")
puts set
adress = set["train"]["adress"]
puts adress

Es ist möglich, dies durch Eingabe der Adresse in config.yml wie folgt anzugeben.

Ergebnis

> <pre>[APIkey]</pre>

Das ist nicht gut.

stringkey = "#{apikey}"
stringkey.slice!("</pre>")
stringkey.slice!("<pre>")
puts "APIKey = #{stringkey}"

Unmittelbar nach dem Hinzufügen ist der Vorgang des Erwerbs des API-Schlüssels vorerst abgeschlossen.

Was ist, wenn Sie angemeldet sind?

Eigentlich habe ich zuerst daran gearbeitet, aber was ist, wenn es nicht der Anmeldebildschirm war? Ich weiß nicht, ob dies passiert, aber wenn dies der Fall ist, wird beim Anmelden ein Fehler verursacht.

page = RedmineController.new
pagetitle = page.Myaccount_access(adress)
puts "pagetitle = #{pagetitle}"

if pagetitle == "Persönliche Einstellungen- redmine" then #Überprüfen Sie, ob Sie angemeldet sind
     apikey = page.GetAPIkey(adress)
     puts "APIKey = #{apikey}"
else
     apikey = page.Login(adress,mail,password) 
end

Der Titel des Bildschirms mit den persönlichen Einstellungen nach der Anmeldung lautete "Persönliche Einstellungen --redmine", daher wurde dies unterstützt.

Hier wird eine Klasse namens RedmineContoroller erstellt, die später beschrieben wird.

Danach habe ich es mit der Redmine des Unternehmens versucht und festgestellt. Die Redmine unseres Unternehmens lautet "Persönliche Einstellungen - [Firmenname] Redmine". Als Ergebnis der Überprüfung sind alle oberen Seiten usw. "[Firmenname] redmine". Mit anderen Worten, es scheint ein Stil von "Persönliche Einstellungen - [Seitenname]" zu sein. Lass uns damit umgehen.

   page = RedmineController.new
   toptitle = page.toptitle(adress)
   pagetitle = page.Myaccount_access(adress)
   puts "pagetitle = #{pagetitle}"

   if pagetitle == "Persönliche Einstellungen- #{toptitle}" then #Überprüfen Sie, ob Sie angemeldet sind
     apikey = page.GetAPIkey(adress)
     puts "APIKey = #{apikey}"
   else
     apikey = page.Login(adress,mail,password) 
   end

Es ist so. Mit anderen Worten, es ist eine Strategie, zuerst den Top-Titel zu erfassen. Lassen Sie uns nun die Klasse "RedmineController" veröffentlichen. Ja, ich muss die toptitle-Methode zweimal einführen, da sie problematisch ist.

class RedmineController

 def toptitle(adress)
	url = "http://#{adress}/"

	charset = nil

	html = open(url) do |page|
	 charaset = page.charset
	 page.read
	end

	contents = Nokogiri::HTML.parse(html,nil,charset)
 return contents.title
 end

 def Myaccount_access(adress)
	url = "http://#{adress}/my/account"

	charset = nil

	html = open(url) do |page|
	 charaset = page.charset
	 page.read
	end

	contents = Nokogiri::HTML.parse(html,nil,charset)
 return contents.title
 end

 def Login(adress,mail,password)
	agent = Mechanize.new
	agent.user_agent = 'Mac Safari'
	agent.get("http://#{adress}/my/api_key") do |page|
	  response = page.form_with(:action => '/login') do |form|
	    formdata = {
	       :mail => mail,
	       :password => password,
	    }
	    form.field_with(:name => 'username').value = formdata[:mail]
	    form.field_with(:name => 'password').value = formdata[:password]
	  end.submit
	 end
	 url = "http://#{adress}/my/api_key"
	 html = agent.get("#{url}").content.toutf8
         contents = Nokogiri::HTML(html, nil, 'utf-8')
         apikey = contents.search("div[@class='box']").search('pre')
         stringkey = "#{apikey}"
	 stringkey.slice!("</pre>")
	 stringkey.slice!("<pre>")
	 puts "APIKey = #{stringkey}"
	 return stringkey
 end

 def GetAPIkey(adress)
        url = "http://#{adress}/my/api_key"

        charset = nil

        html = open(url) do |page|
         charaset = page.charset
         page.read
        end

        contents = Nokogiri::HTML.parse(html,nil,charset)
	apikey = contents.search("div[@class='box']").search('pre')
        stringkey = "#{apikey}"
	stringkey.slice!("</pre>")
	stringkey.slice!("<pre>")
	puts "APIKey = #{stringkey}"
	return stringkey
 end

end

Und zur Vollendung

Danach muss ein Prozess erstellt werden, um mithilfe der API etwas zu tun. Lassen Sie uns also den Prozess verschieben, um den API-Schlüssel in die Methode zu übernehmen.

class Getter
 def APIKey_Getter(adress,mail,password)
   page = RedmineController.new
   toptitle = page.toptitle(adress)
   pagetitle = page.Myaccount_access(adress)
   puts "pagetitle = #{pagetitle}"

   if pagetitle == "Persönliche Einstellungen- #{toptitle}" then #Überprüfen Sie, ob Sie angemeldet sind
     apikey = page.GetAPIkey(adress)
     puts "APIKey = #{apikey}"
   else
     apikey = page.Login(adress,mail,password) 
   end
   return apikey
 end

Übrigens füge ich jetzt Methoden hinzu, um verschiedene APIs zu dieser Getter-Klasse aufzurufen.

Das ganze Bild

Mit den oben genannten abgeschlossen. Das ganze Bild ist so.

require 'open-uri'
require 'nokogiri' #Wird verwendet, um den API-Schlüssel abzurufen
require 'mechanize' #Wird für die Anmeldung verwendet
require 'yaml' #Wird zum Lesen der Konfiguration verwendet
require 'io/console' #Wird für die Abkürzung von Pasoward verwendet

class RedmineController

 def toptitle(adress)
	url = "http://#{adress}/"

	charset = nil

	html = open(url) do |page|
	 charaset = page.charset
	 page.read
	end

	contents = Nokogiri::HTML.parse(html,nil,charset)
 return contents.title
 end

 def Myaccount_access(adress)
	url = "http://#{adress}/my/account"

	charset = nil

	html = open(url) do |page|
	 charaset = page.charset
	 page.read
	end

	contents = Nokogiri::HTML.parse(html,nil,charset)
 return contents.title
 end

 def Login(adress,mail,password)
	agent = Mechanize.new
	agent.user_agent = 'Mac Safari'
	agent.get("http://#{adress}/my/api_key") do |page|
	  response = page.form_with(:action => '/login') do |form|
	    formdata = {
	       :mail => mail,
	       :password => password,
	    }
	    form.field_with(:name => 'username').value = formdata[:mail]
	    form.field_with(:name => 'password').value = formdata[:password]
	  end.submit
	 end
	 url = "http://#{adress}/my/api_key"
	 html = agent.get("#{url}").content.toutf8
         contents = Nokogiri::HTML(html, nil, 'utf-8')
         apikey = contents.search("div[@class='box']").search('pre')
         stringkey = "#{apikey}"
	 stringkey.slice!("</pre>")
	 stringkey.slice!("<pre>")
	 puts "APIKey = #{stringkey}"
	 return stringkey
 end

 def GetAPIkey(adress)
        url = "http://#{adress}/my/api_key"

        charset = nil

        html = open(url) do |page|
         charaset = page.charset
         page.read
        end

        contents = Nokogiri::HTML.parse(html,nil,charset)
	apikey = contents.search("div[@class='box']").search('pre')
        stringkey = "#{apikey}"
	stringkey.slice!("</pre>")
	stringkey.slice!("<pre>")
	puts "APIKey = #{stringkey}"
	return stringkey
 end
end

class Getter
 def APIKey_Getter(adress,mail,password)
   page = RedmineController.new
   toptitle = page.toptitle(adress)
   pagetitle = page.Myaccount_access(adress)
   puts "pagetitle = #{pagetitle}"

   if pagetitle == "Persönliche Einstellungen- #{toptitle}" then #Überprüfen Sie, ob Sie angemeldet sind
     apikey = page.GetAPIkey(adress)
     puts "APIKey = #{apikey}"
   else
     apikey = page.Login(adress,mail,password) 
   end
   return apikey
 end
end


#Die Verarbeitung beginnt hier. Tatsächlich erhalten Sie Informationen per Get oder Post mit Sinatra
puts "Bitte geben Sie Ihren Kontonamen ein"
mail = gets
mail.chomp!
puts "Bitte geben Sie das Passwort ein (nicht angezeigt, aber Sie können es eingeben)"
password = STDIN.noecho(&:gets)
password.chomp!
#Eigentlich wird es nicht mit get erworben, sondern vorerst eingestellt. Schließlich verschwindet all dieser Bereich

set = YAML.load_file("config.yml")
puts set
adress = set["train"]["adress"]
puts adress
f = Getter.new
apikey = f.APIKey_Getter(adress,mail,password) 
puts "APIKey = #{apikey}"

Vielen Dank für Ihre Geduld.

Recommended Posts

Versuchen Sie, den API-Schlüssel von Redmine mit Ruby zu erhalten
[swift5] Versuchen Sie, einen API-Client auf verschiedene Arten zu erstellen
Was ich mit der Redmine REST API süchtig gemacht habe
Jetzt ist es an der Zeit, mit der Stream-API zu beginnen
[Ruby on Rails] Leseversuch (: [],: Schlüssel)
Wie fange ich mit schlank an?
Versuchen Sie, Yuma in Ruby zu implementieren
Memo mit Struts2 + Ajax zu bekommen
Ich erhalte einen Ruby-Versionsfehler, wenn ich versuche, Rails zu starten.
Ich habe versucht, mit Web Assembly zu beginnen
[Hinweis] Erste Schritte mit Rspec
Versuchen Sie, mithilfe der API eine Karte von Jave an Trello auszustellen oder zu erhalten
Versuchen Sie, eine Anmeldefunktion mit Spring-Boot zu implementieren
Einführung in "Einführung in die praktische Rostprogrammierung" (Tag 4) Aufrufen von Rust von Ruby
Android-Entwicklung - WEB-Zugriff (GET) Versuchen Sie, Daten durch Kommunikation mit der Außenwelt abzurufen. ~
So löschen Sie Daten mit einem externen Schlüssel
Verwenden Sie MyBatis, um eine Karte mit einem Schlüssel als Kennung und einem Wert als Entität abzurufen
Konvertieren Sie mit Ruby von JSON nach TSV und von TSV nach JSON
[Ruby] Grundlegender Schlüssel, um beim Refactoring stark zu sein
Versuchen Sie es mit einem GPS-Empfänger-Kit mit Raspberry Pi 3 (Ruby).
Versuchen Sie, die Anmeldefunktion mit Spring Boot zu implementieren
Verwendung der Java-API mit Lambda-Ausdrücken
[Java] Holen Sie sich Bilder mit der Google Custom Search API
AtCoder ABC127 D Hash mit Ruby 2.7.1 zu lösen
Holen Sie sich Daten mit der API, die mit dem Befehl curl erstellt wurde
So erstellen Sie eine API mit GraphQL und Rails
Versuchen Sie, TCP / IP + NIO mit JAVA zu implementieren
Rails-Anfänger haben versucht, mit RSpec zu beginnen
Versuchen Sie, die Migration mit Spring Boot Flyway zu automatisieren
So löschen Sie eine Ressourcendatei mit Spring-Boot
Versuchen Sie, Hallo Welt mit Frühling + Gradle anzuzeigen
Erste Schritte mit Doma-Einführung in die Kriterien-API
Versuchen Sie, das gemeinsame Layout mit Schienen zusammenzufassen
Ich möchte den Wert in Ruby erhalten
Einführung in Ruby 2
Ruby API Problem
Ruby API Problem
Versuchen Sie Ruby Minitest
Ich habe versucht, was ich mit Stream leise versuchen wollte.
[Einführung] Erstellen Sie eine Ruby on Rails-Anwendung
Ordnen Sie DTO automatisch Entitäten mit der Spring Boot-API zu
So erstellen Sie eine mit Ruby erstellte LINE-Messaging-Funktion
Rails / Ruby: So erhalten Sie HTML-Text für Mail
[Spring Boot] Benutzerinformationen mit Rest API abrufen (Anfänger)
Konvertieren von TSV-Dateien in CSV-Dateien (mit Stückliste) in Ruby
Ich habe versucht, mit Spring Data JPA zu beginnen