Essayez d'obtenir la clé API de redmine avec ruby

Contexte

On m'a demandé de pouvoir obtenir la clé API redmine en utilisant ruby au travail. J'ai vu l'achèvement pour le moment, donc je vais le résumer au lieu de mon mémorandum.   L'article n'a été créé que par un programmeur débutant au cours de la première année de sa vie professionnelle qui a obtenu un emploi de programmeur simplement en étudiant par lui-même, en répétant la recherche et la copie. S'il y a une personne comme moi, j'espère que cet article à lui seul sera un succès.

Méthode

Je l'ai d'abord cherché, mais je n'ai pas trouvé la description correspondante. En supposant que la clé API est reçue de l'écran de configuration personnelle de redmine et entrée dans le code, je n'ai pas pu trouver un moyen d'obtenir la clé API par programme. Cependant, à la suite d'une recherche excluant l'état du rubis, l'article suivant a été trouvé.

Comment obtenir diverses données de Redmine JavaScript https://qiita.com/forenoonM/items/7f42701b2ea40353a820

Cet article décrit comment obtenir la clé API à l'aide de JavaScript. En gros, c'est une méthode utilisant le grattage.

Pratique de grattage

Je vois, grattage? Eh bien, embarrassant, je ne savais même pas ce qu'était le grattage. Après tout, je suis un débutant qui vient d'étudier le rubis par moi-même. J'ai donc cherché un moyen de gratter avec du rubis et suis arrivé sur le site suivant.

[Comprendre en 5 minutes] Expliquez les bases du grattage avec Ruby! https://www.sejuku.net/blog/13230

C'est le code créé de cette manière

equire 'open-uri'
require 'nokogiri' #Utilisé pour obtenir la clé API
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

Eh bien, quand je le déplace réellement, il ne bouge pas. À la suite de diverses enquêtes, j'ai remarqué qu'il s'arrêtait à l'écran de connexion.

Cela signifie que vous devez créer un processus de connexion

Créer un processus de connexion

Donc, comme d'habitude, je suis arrivé sur cette page en cherchant.

Connectez-vous avec Mechanize et grattez https://qiita.com/katsuyuki/items/1a78360988d96eec1d54

Je le comprends parfaitement.

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

Seule la partie supplémentaire a été extraite.

Au fait, concernant # {adresse}, il a dit: "Je teste localement maintenant, mais après cela, je l'exécuterai sur la société redmine et le client redmine."

require 'yaml' #Utilisé pour lire la configuration

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

Il est possible de spécifier en saisissant l'adresse dans config.yml comme ceci.

résultat

> <pre>[APIkey]</pre>

Ce n'est pas bien.

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

Immédiatement après l'ajout de cela, le processus d'acquisition de la clé API est terminé pour le moment.

Et si vous êtes connecté?

En fait, je travaillais dessus en premier, mais que faire si ce n'était pas l'écran de connexion? Je ne sais pas si cela se produit, mais si c'est le cas, cela entraînera une erreur lors du processus de connexion.

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

if pagetitle == "Paramètres personnels- redmine" then #Vérifiez si vous êtes connecté
     apikey = page.GetAPIkey(adress)
     puts "APIKey = #{apikey}"
else
     apikey = page.Login(adress,mail,password) 
end

Le titre de l'écran des paramètres personnels après la connexion était «Paramètres personnels --redmine», ce qui était donc pris en charge.

Une classe appelée RedmineContoroller est créée ici, et cette classe sera décrite plus tard.

Après cela, je l'ai essayé avec la mine rouge de l'entreprise et j'ai remarqué. La redmine de notre société est "Paramètres personnels - [Nom de la société] redmine". Lorsque j'ai vérifié, toutes les premières pages étaient "[nom de l'entreprise] redmine". En d'autres termes, cela semble être un style de "Paramètres personnels - [Nom de la page]". Traitons-y.

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

   if pagetitle == "Paramètres personnels- #{toptitle}" then #Vérifiez si vous êtes connecté
     apikey = page.GetAPIkey(adress)
     puts "APIKey = #{apikey}"
   else
     apikey = page.Login(adress,mail,password) 
   end

C'est comme ça. En d'autres termes, c'est une stratégie pour saisir le premier titre en premier. Maintenant, publions la classe "RedmineController". Oui, je dois introduire la méthode toptitle deux fois car elle est gênante.

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

Et à la fin

Après cela, il est nécessaire de créer un processus pour faire quelque chose à l'aide de l'API, alors poussons le processus pour obtenir la clé API dans la méthode.

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 == "Paramètres personnels- #{toptitle}" then #Vérifiez si vous êtes connecté
     apikey = page.GetAPIkey(adress)
     puts "APIKey = #{apikey}"
   else
     apikey = page.Login(adress,mail,password) 
   end
   return apikey
 end

À propos, après cela, j'ajoute maintenant des méthodes pour appeler diverses API à cette classe getter.

L'image entière

Complété avec ce qui précède. L'image entière est comme ça.

require 'open-uri'
require 'nokogiri' #Utilisé pour obtenir la clé API
require 'mechanize' #Utilisé pour la connexion
require 'yaml' #Utilisé pour lire la configuration
require 'io/console' #Utilisé pour l'abréviation de Pasoward

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 == "Paramètres personnels- #{toptitle}" then #Vérifiez si vous êtes connecté
     apikey = page.GetAPIkey(adress)
     puts "APIKey = #{apikey}"
   else
     apikey = page.Login(adress,mail,password) 
   end
   return apikey
 end
end


#Le traitement commence à partir d'ici. Recevez en fait des informations par get ou par courrier avec sinatra
puts "Veuillez saisir le nom de votre compte"
mail = gets
mail.chomp!
puts "Veuillez saisir le mot de passe (non affiché mais vous pouvez le saisir)"
password = STDIN.noecho(&:gets)
password.chomp!
#En fait, il n'est pas acquis à l'aide de gets, mais il est défini pour le moment. Finalement, toute cette plage disparaît

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}"

Merci pour votre patience.

Recommended Posts

Essayez d'obtenir la clé API de redmine avec ruby
[swift5] Essayez de créer un client API avec différentes méthodes
Ce à quoi j'étais accro avec l'API REST Redmine
Il est maintenant temps de commencer avec l'API Stream
[Ruby on Rails] Read try (: [] ,: key)
Comment démarrer avec Slim
Essayez d'implémenter Yuma dans Ruby
Mémo à obtenir avec Struts2 + Ajax
J'obtiens une erreur de version de Ruby lorsque j'essaye de démarrer Rails.
J'ai essayé de démarrer avec Web Assembly
Rubocop se met en colère quand j'essaye de remplir zéro (remplir 0) avec Ruby
[Note] Comment démarrer avec Rspec
Essayez d'émettre ou d'obtenir une carte de Jave à Trello à l'aide de l'API
Essayez d'implémenter une fonction de connexion avec Spring-Boot
Présentation de «Introduction à la programmation pratique de Rust» (jour 4) Appel de Rust depuis Ruby
Développement Android-Accès WEB (GET) Essayez d'obtenir des données en communiquant avec l'extérieur. ~
Comment supprimer des données avec une clé externe
Utilisez MyBatis pour obtenir une carte avec une clé comme identifiant et une valeur comme entité
Conversion de JSON en TSV et TSV en JSON avec Ruby
[Ruby] Clé de base pour être fort dans la refactorisation
Essayez d'utiliser le kit de récepteur GPS avec Raspberry Pi 3 (Ruby)
Essayez d'implémenter la fonction de connexion avec Spring Boot
Comment utiliser l'API Java avec des expressions lambda
[Java] Obtenez des images avec l'API Google Custom Search
AtCoder ABC127 D hash à résoudre avec Ruby 2.7.1
Obtenez des données avec une API créée par la commande curl
Comment créer une API avec GraphQL et Rails
Essayez d'implémenter TCP / IP + NIO avec JAVA
Les débutants de Rails ont essayé de se lancer avec RSpec
Essayez d'automatiser la migration avec Spring Boot Flyway
Comment sortir un fichier de ressources avec spring-boot
Essayez d'afficher Hello World avec Spring + Gradle
Premiers pas avec Doma - Introduction à l'API Criteria
Essayez de résumer la disposition commune avec des rails
Je veux obtenir la valeur en Ruby
Introduction à Ruby 2
Problème d'API ruby
Problème d'API ruby
Essayez Ruby Minitest
J'ai essayé ce que je voulais essayer avec Stream doucement.
[Introduction] Créer une application Ruby on Rails
Mappez automatiquement DTO aux entités avec l'API Spring Boot
Comment créer une fonction de messagerie LINE avec Ruby
Rails / Ruby: Comment obtenir du texte HTML pour Mail
[Spring Boot] Obtenez des informations utilisateur avec l'API Rest (débutant)
Conversion du fichier TSV en fichier CSV (avec BOM) en Ruby
J'ai essayé de démarrer avec Spring Data JPA