[PYTHON] L'histoire du développement d'une application WEB qui génère automatiquement des copies de capture [MeCab]

Site de service

MakeLike https://melikeke.sakura.ne.jp/malike/intro

Aperçu

Utilisez Mecab de Python pour générer des «phrases similaires» à partir de diverses données d'enseignants ・ Généré à partir de la catégorie ・ Généré à partir d'un fichier ・ Généré à partir d'une entrée directe Les données de l'enseignant peuvent être spécifiées à partir des trois modèles de.

fonction

Génération automatique de copie de capture

・ Généré à partir de la catégorie ・ Généré à partir d'un fichier ・ Généré à partir d'une entrée directe

Fonction de connexion

Inscription des membres S'identifier Notification d'inscription des membres réinitialiser le mot de passe

Fonction préférée

la mise en oeuvre

environnement

Serveur Sakura

l'extrémité avant

Laravel

Partie de base

Utilisation de modèles

Rendre la partie de mise en page commune dans le modèle de lame de Laravel http://cly7796.net/wp/php/to-a-common-layout-in-blade-template-of-laravel/


Système d'authentification de connexion

Comment implémenter une fonction de connexion rapide dans Laravel https://php-junkie.net/framework/laravel/login/

Lorsque "Commande" make: auth "n'est pas défini." Apparaît https://qiita.com/daisu_yamazaki/items/a914a16ca1640334d7a5

[Authentification de l'utilisateur avec Laravel7_8] Authentifiez-vous par e-mail lors du changement d'adresse e-mail https://qiita.com/crosawassant/items/018b29ab770c0a373bc9

Examinons le comportement de l'authentification standard de Laravel (Auth) https://qiita.com/zaburo/items/9fcf0f4c771e011a4d35


Notification automatique lors de l'inscription en tant que membre

Les notifications par e-mail et les notifications Slack peuvent être envoyées à l'aide de l'une des méthodes suivantes.

Laravel Si vous lisez ceci, vous pouvez définir des événements et des écouteurs Laravel https://reffect.co.jp/laravel/laravel-event-listener#i-8

Google Analytics Recevez des alertes de Google Analytics https://www.ad-market.jp/column/2020/04/20200420.html


Fonction courrier

Configurez la fonction de messagerie de Laravel pour envoyer un e-mail de réinitialisation de mot de passe.

"MailTrap" pendant le développement local Dans l'environnement de production, nous avons mis en place le SMTP de «Sakura Server» et confirmé la communication.

Test de transmission d'e-mails avec Laravel Mail Trap Memorandum https://qiita.com/ryomaDsakamoto/items/e9d3a2c258dbfc66c524

Définissez le SMTP du serveur Sakura dans le serveur SMTP de Laravel https://laraweb.net/tutorial/1265/

Essayez d'utiliser la fonction sophistiquée d'envoi de courrier électronique «Laravel» https://liginc.co.jp/369690

Laravel5.7: Envoyer un e-mail de réinitialisation de mot de passe japonais https://qiita.com/sutara79/items/0ea48847f5565aacceea


Cadre japonais

Lors de la configuration du japonais avec Laravel, Les paramètres peuvent être appliqués en écrivant dans ja.json.

/resources/lang/ja.json


{
    "Click link below and reset password.": "Veuillez accéder à l'URL ci-dessous et réinitialiser votre mot de passe.",
    "If you did not request a password reset, no further action is required.": "Si vous ne connaissez pas cet e-mail, supprimez-le simplement.",
}

blade.php


<p>
    {{ __('Click link below and reset password.') }}<br>
    {{ __('If you did not request a password reset, no further action is required.') }}
</p>

Affichage réel image.png


Pièce générée

Implémentation de la partie d'affichage "Générer à partir de la catégorie"

Le menu déroulant des catégories fait les choix de changement de "Catégorie 2" en association avec "Catégorie 1".


・ Lorsque la catégorie 1 est "paroles"


・ Lorsque la catégorie 1 est "roman"


relation

category1.id = category2.parent_id


categori1


categori2


référence

Comment créer une boîte de sélection parent-enfant comme une catégorie / sous-catégorie dans laravel https://www.messiahworks.com/archives/12202


Implémentation de la partie de traitement "Générer à partir de la catégorie"

Définissez le chemin des données de l'enseignant à lire par Storage en fonction de la valeur spécifiée dans la catégorie.

contoloer.php


$input = $request->input();
$category1  = Arr::get($input, 'category1');
$category2  = Arr::get($input, 'category2');
$path = 'public/constText/';
$path .= $category1 . '/';
$path .= $category2 . '.txt';

Structure de constText image.png


Implémentation de la partie "Générer à partir d'un fichier"

Utilisez la fonction de stockage de Laravel pour implémenter le processus de téléchargement. Cette fois, nous allons le limiter aux données texte uniquement, définissez l'extension comme suit. ·SMS ・ Csv ・ Xls ・ Xlsx

référence Explication détaillée sur la façon de télécharger des fichiers avec Laravel https://reffect.co.jp/laravel/how_to_upload_file_in_laravel

J'ai essayé de résumer le fonctionnement des fichiers et des répertoires en utilisant Storage in Laravel https://qiita.com/t1k2a/items/50081988363cf2fa1bca


Implémentation de la partie "Générer à partir de l'entrée directe"

"Générer à partir du fichier" est exécuté dans le flux ci-dessus, "Générer à partir d'une entrée directe" est également exécuté en utilisant la fonction de stockage.

Flux de production à partir de l'entrée directe Enregistrer la valeur de textarea sous forme de fichier texte dans le stockage Ci-dessous, le même traitement que "générer à partir d'un fichier"

Fin du serveur

Python La pièce générée automatiquement par MeCab est résumée dans l'article suivant.

référence Copie de capture générée automatiquement [Python] https://qiita.com/SyogoSuganoya/items/ba542f686104811e2d6b


Exécutez Python à partir de PHP

Lors d'un événement de déclenchement tel que le bouton d'entrée implémenté dans Laravel Vous permet d'implémenter Python.

Utilisez la fonction exec de PHP pour exécuter Python.

référence Lier PHP et Python à partir de zéro sur Laravel https://qiita.com/SwitchBlade/items/96ed4ea425ef2d758f71

PHP --Résumé de la relation entre la gestion des erreurs exec () et la sortie d'erreur standard https://qiita.com/smd8122/items/65b552f1d53bfb7fad9a


Ajax

De base

Création d'un écran de visualisation de commentaires dynamique à l'aide de Laravel et Ajax https://www.merges.co.jp/archives/1980

Utiliser Ajax (jQuery) avec Laravel https://pointsandlines.jp/server-side/php/laravel-ajax

Traitement Ajax en passant des valeurs avec Laravel et Ajax. https://niwacan.com/1619-laravel-ajax/


Affichage des phrases générées

image.png


Ajax est utilisé pour afficher la zone "texte généré" après avoir appuyé sur le bouton générer. Afficher les "\ $ sorties" de la fonction exec de PHP dans le texte généré. $ sorties contient la chaîne imprimée pendant l'exécution de Python

controller.php


exec($command , $outputs, $return_var);

$data = [
	'outputs' => $outputs,
	'return_var' => $return_var,
];
return response()->json($data);

pythonCall.js


var params = {
	headers: {  
		'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
	},
	url: url,
	method: 'post',
	dataType: 'json',
	data: paramData,
	//S'exécute jusqu'à ce que la demande soit terminée
	beforeSend: function(){
		$('h3').text('Chargement');
		$("input").attr("disabled","true"); 
		$('.wrapper .button').addClass('pushed');
		$('.heart-check').prop('checked', false); //Supprimer tous les éléments cochés
	}
};

$.ajax(
	params
).done(function( data ) {
	//Initialisation du texte généré
	$('input.sentence').val('');
	
	//Saisie des phrases générées
	for(var i = 0; i < data.outputs.length && i < 5; i++){
		$('input.sentence').eq(i).val(data.outputs[i]);
	}
}

Fonction préférée

Enregistrement préféré des phrases générées et Gérez vos textes préférés sur Ma page image.png


La fonction favorite utilise Ajax et la traite de manière asynchrone.

controller.php


//Affichage de l'écran de liste
public function index(Request $request) {

	$posts = Favorite_sentence::where('user_id', $request->user()->id) //$Obtenir des articles par utilisateur
		->orderBy('created_at', 'desc') //Organiser les articles par ordre chronologique
		->paginate(10); //Pagination; 

	return view('user.mypage', [
		'posts' => $posts, // $Passer l'article rédigé par l'utilisateur pour l'afficher
	]);
}

//Cliquez sur le symbole du cœur(S'inscrire ou supprimer)
public function ajaxlike(Request $request) {

	// $user_id = $request->user()->id;
	$user_id = Auth::user()->id;
	$post_id = $request->post_id;
	$sentence = $request->sentence;

	$like = new Favorite_sentence;
	$exist = Favorite_sentence::where('id', $post_id)->get();
	$isExist = $exist->isEmpty();

	if ($isExist) {
		//Créer un nouvel enregistrement dans le tableau des likes s'il est vide (pas encore "aimé")
		$like = new Favorite_sentence;
		$like->user_id = $user_id;
		$like->sentence = $sentence;
		$like->save();

		$post_id = $like->id;
		$command = 'insert';

	} else {
		//Confirmation de l'existence de phrases préférées
		Favorite_sentence::findOrFail($post_id);
		//Supprimer les enregistrements dans la table des likes
		$like = Favorite_sentence::where('id', $post_id)
		->delete();

		$command = 'delete';
	}

	$data = [
		'user_id' => $user_id,
		'post_id' => $post_id,
		'sentence' => $sentence,
		'command' => $command,
	];
	//Renvoie la valeur de l'argument à ajax avec la description suivante
	return response()->json($data);
}

likeSentence.js


var like = $('.heart-label');
var likePostId;
var sentence;

like.on('click', function () {

	var $this = $(this);
	//ID de la phrase préférée
	likePostId = $this.parent().parent().find(".sentence").attr('data-postid');
	//Phrases préférées
	sentence = $this.parent().parent().find(".sentence").val();
	
	//Le texte favori est vide
	if (!sentence) {
		return;
	}
	
	$.ajax({
		headers: {
			'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
		},
		url: '/ajaxlike',
		type: 'POST',
		data: {
			'post_id': likePostId ,
			'sentence': sentence , 
		},
	}).done(function (data) {            
		if(data.command = 'insert') {
			$this.parent().parent().find(".sentence").attr('data-postid', data.post_id);
		}
});

Libération

Utiliser "Sakura Server" dans un environnement de production

Construction de l'environnement Python / MeCab

Envoie le résultat de l'analyse morphologique avec Mecab vers un navigateur WEB compatible avec le serveur Sakura / UTF-8 https://qiita.com/Jshirius/items/ac3ca66a2d5262b98b58

Installez mecab sur le serveur partagé Sakura et appelez-le depuis python https://qiita.com/Jshirius/items/3a067486e2a693544c32


Quand MeCab peut être exécuté depuis un terminal mais pas depuis un appel PHP ...

Essayez d'abord d'appeler Python avec le chemin complet

Une histoire que j'ai eu du mal à appeler python avec la fonction exec de php sur le serveur X https://hazukei.com/1259/


Ajouter des packages de site

Si cela ne fonctionne pas, comparez les "packages de site" entre le terminal et PHP.

import site
site.USER_SITE

Ajouter des diffs pour rendre les packages installés exécutables

import sys
sys.path.append('vendor\Lib\site-packages')

référence Installer le module Python sur le serveur de location Sakura https://emptypage.jp/notes/sakura-python.html

Un ingénieur actif explique comment vérifier et définir la destination d'installation du module Python [pour les débutants] https://techacademy.jp/magazine/46510

Laravel [0001] SSH dans le serveur de location de Sakura et installer Laravel https://www.failibere.com/development_memo/lalavel/0001

Créer un lien symbolique vers le stockage sur le serveur Sakura https://blog.hiroyuki90.com/articles/laravelで作成したwebアプリをレンタルサーバに公開する/

Recommended Posts

L'histoire du développement d'une application WEB qui génère automatiquement des copies de capture [MeCab]
L'histoire de la création d'une application Web qui enregistre des lectures approfondies avec Django
Une histoire qui réduit l'effort de fonctionnement / maintenance
Une histoire qui a analysé la livraison de Nico Nama.
Un outil qui transforme automatiquement le gacha de Soshage
L'histoire du remontage du serveur d'application
L'histoire de l'exportation d'un programme
L'histoire du travail de sortie de l'application que Google ne raconte pas
L'histoire de la création d'un site qui répertorie les dates de sortie des livres
L'histoire de la création d'un module qui ignore le courrier avec python
L'histoire de la mise en place de MeCab dans Ubuntu 16.04
L'histoire du traitement A du blackjack (python)
J'ai fait un calendrier qui met à jour automatiquement le calendrier de distribution de Vtuber
L'histoire de la création d'un package qui accélère le fonctionnement de Juman (Juman ++) & KNP
[Python] J'ai créé un code de scraping web qui acquiert automatiquement le titre de l'actualité et l'URL de Nihon Keizai Shimbun.
L'histoire de l'adresse IPv6 que je souhaite conserver au minimum
L'histoire de la fabrication d'une boîte qui interconnecte la mémoire AL de Pepper et MQTT
Je souhaite créer une application WEB en utilisant les données de League of Legends ①
L'histoire de la création d'un Line Bot qui nous raconte le calendrier de la programmation du concours
L'histoire de la création d'un générateur d'icônes mel
L'histoire de l'introduction d'une fonction d'authentification multifacteur utilisant un mot de passe à usage unique dans une application Java
J'ai fait un calendrier qui met à jour automatiquement le calendrier de distribution de Vtuber (édition Google Calendar)
L'histoire du lancement d'un serveur Minecraft depuis Discord
[Python] Un programme qui compte le nombre de vallées
#Une fonction qui renvoie le code de caractère d'une chaîne de caractères
L'histoire de la création d'un réseau neuronal de génération musicale
Une histoire qui a eu du mal avec l'ensemble commun HTTP_PROXY = ~
Générer cette forme du fond d'une bouteille pour animaux de compagnie
Une histoire sur le changement du nom principal de BlueZ
L'histoire selon laquelle la valeur de retour de tape.gradient () était None
Le problème Zip 4 Gbyte est une histoire du passé
[Python] Un programme qui compare les positions des kangourous.
Clustering G-means qui détermine automatiquement le nombre de clusters
L'histoire de sys.path.append ()
Créez un bot qui ne renvoie que le résultat de l'analyse morphologique avec MeCab avec Discord
Créez une application Web qui reconnaît les nombres avec un réseau neuronal
L'histoire de la création d'un canal VIP dans le chatwork en interne
L'histoire du champ de modèle Django disparaissant de la classe
L'histoire de la création d'une base de données à l'aide de l'API Google Analytics
L'histoire de la création d'un bot de boîte à questions avec discord.py
Script Python qui compare le contenu de deux répertoires
Une histoire qui a vérifié si le nombre de coronas augmente vraiment rapidement chez les jeunes
Notez que j'étais accro à accéder à la base de données avec mysql.connector de Python en utilisant une application Web
Envoie le résultat de l'analyse morphologique avec Mecab vers un navigateur WEB compatible avec le serveur Sakura / UTF-8
Une petite histoire addictive avec les permissions du répertoire spécifié par expdp (pour les débutants)
L'histoire de la création d'un outil qui fonctionne sur Mac et Windows sur le site de développement de jeux
L'histoire de la création d'un Bot qui affiche les membres actifs dans un canal spécifique de Slack avec Python
Lors de l'incrémentation de la valeur d'une clé qui n'existe pas
Une histoire coincée avec l'installation de la bibliothèque de machine learning JAX
L'histoire selon laquelle la version de python 3.7.7 n'était pas adaptée à Heroku
pandas Récupère le nom d'une colonne contenant un caractère spécifique
[python, ruby] sélénium-Obtenez le contenu d'une page Web avec le pilote Web
L'histoire de l'erreur de hachage est apparue lors de l'utilisation de Pipenv
Une formule qui calcule simplement l'âge à partir de la date de naissance
L'histoire de la création d'un pilote standard pour db avec python.
Une fonction qui mesure le temps de traitement d'une méthode en python