GOOGLE ADS

samedi 30 avril 2022

Connecteur Kafka et Schema Registry - Erreur lors de la récupération du schéma Avro - Objet introuvable

J'ai un sujet qui finira par contenir de nombreux schémas différents. Pour l'instant il n'en a qu'un. J'ai créé un travail de connexion via REST comme ceci :

{
"name":"com.mycompany.sinks.GcsSinkConnector-auth2",
"config": {
"connector.class": "com.mycompany.sinks.GcsSinkConnector",
"topics": "auth.events",
"flush.size": 3,
"my.setting":"bar",
"key.converter":"org.apache.kafka.connect.storage.StringConverter",
"key.deserializer":"org.apache.kafka.common.serialization.StringDerserializer",
"value.converter":"io.confluent.connect.avro.AvroConverter",
"value.converter.schema.registry.url":"http://schema-registry-service:8081",
"value.subject.name.strategy":"io.confluent.kafka.serializers.subject.RecordNameStrategy",
"group.id":"account-archiver"
}
}

J'envoie ensuite un message à ce sujet avec une clé de chaîne et une charge utile sérialisée avro. Si j'inspecte le sujet dans le centre de contrôle, je vois les données correctement désérialisées passer. En regardant la sortie de l'instance de connexion, je vois cela dans les journaux

RROR WorkerSinkTask{id=com.mycompany.sinks.GcsSinkConnector-auth2-0} Task threw an uncaught and unrecoverable exception (org.apache.kafka.connect.runtime.WorkerTask)
org.apache.kafka.connect.errors.ConnectException: Tolerance exceeded in error handler
at org.apache.kafka.connect.runtime.errors.RetryWithToleranceOperator.execAndHandleError(RetryWithToleranceOperator.java:178)
at org.apache.kafka.connect.runtime.errors.RetryWithToleranceOperator.execute(RetryWithToleranceOperator.java:104)
at org.apache.kafka.connect.runtime.WorkerSinkTask.convertAndTransformRecord(WorkerSinkTask.java:487)
at org.apache.kafka.connect.runtime.WorkerSinkTask.convertMessages(WorkerSinkTask.java:464)
at org.apache.kafka.connect.runtime.WorkerSinkTask.poll(WorkerSinkTask.java:320)
at org.apache.kafka.connect.runtime.WorkerSinkTask.iteration(WorkerSinkTask.java:224)
at org.apache.kafka.connect.runtime.WorkerSinkTask.execute(WorkerSinkTask.java:192)
at org.apache.kafka.connect.runtime.WorkerTask.doRun(WorkerTask.java:175)
at org.apache.kafka.connect.runtime.WorkerTask.run(WorkerTask.java:219)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.apache.kafka.connect.errors.DataException: Failed to deserialize data for topic auth.events to Avro:
at io.confluent.connect.avro.AvroConverter.toConnectData(AvroConverter.java:107)
at org.apache.kafka.connect.runtime.WorkerSinkTask.lambda$convertAndTransformRecord$1(WorkerSinkTask.java:487)
at org.apache.kafka.connect.runtime.errors.RetryWithToleranceOperator.execAndRetry(RetryWithToleranceOperator.java:128)
at org.apache.kafka.connect.runtime.errors.RetryWithToleranceOperator.execAndHandleError(RetryWithToleranceOperator.java:162)
... 13 more
Caused by: org.apache.kafka.common.errors.SerializationException: Error retrieving Avro schema for id 7
Caused by: io.confluent.kafka.schemaregistry.client.rest.exceptions.RestClientException: Subject not found.; error code: 40401
at io.confluent.kafka.schemaregistry.client.rest.RestService.sendHttpRequest(RestService.java:226)
at io.confluent.kafka.schemaregistry.client.rest.RestService.httpRequest(RestService.java:252)
at io.confluent.kafka.schemaregistry.client.rest.RestService.lookUpSubjectVersion(RestService.java:319)
at io.confluent.kafka.schemaregistry.client.rest.RestService.lookUpSubjectVersion(RestService.java:307)
at io.confluent.kafka.schemaregistry.client.CachedSchemaRegistryClient.getVersionFromRegistry(CachedSchemaRegistryClient.java:158)
at io.confluent.kafka.schemaregistry.client.CachedSchemaRegistryClient.getVersion(CachedSchemaRegistryClient.java:271)
at io.confluent.kafka.serializers.AbstractKafkaAvroDeserializer.schemaVersion(AbstractKafkaAvroDeserializer.java:184)
at io.confluent.kafka.serializers.AbstractKafkaAvroDeserializer.deserialize(AbstractKafkaAvroDeserializer.java:153)
at io.confluent.kafka.serializers.AbstractKafkaAvroDeserializer.deserializeWithSchemaAndVersion(AbstractKafkaAvroDeserializer.java:215)
at io.confluent.connect.avro.AvroConverter$Deserializer.deserialize(AvroConverter.java:145)
at io.confluent.connect.avro.AvroConverter.toConnectData(AvroConverter.java:90)
at org.apache.kafka.connect.runtime.WorkerSinkTask.lambda$convertAndTransformRecord$1(WorkerSinkTask.java:487)
at org.apache.kafka.connect.runtime.errors.RetryWithToleranceOperator.execAndRetry(RetryWithToleranceOperator.java:128)
at org.apache.kafka.connect.runtime.errors.RetryWithToleranceOperator.execAndHandleError(RetryWithToleranceOperator.java:162)
at org.apache.kafka.connect.runtime.errors.RetryWithToleranceOperator.execute(RetryWithToleranceOperator.java:104)
at org.apache.kafka.connect.runtime.WorkerSinkTask.convertAndTransformRecord(WorkerSinkTask.java:487)
at org.apache.kafka.connect.runtime.WorkerSinkTask.convertMessages(WorkerSinkTask.java:464)
at org.apache.kafka.connect.runtime.WorkerSinkTask.poll(WorkerSinkTask.java:320)
at org.apache.kafka.connect.runtime.WorkerSinkTask.iteration(WorkerSinkTask.java:224)
at org.apache.kafka.connect.runtime.WorkerSinkTask.execute(WorkerSinkTask.java:192)
at org.apache.kafka.connect.runtime.WorkerTask.doRun(WorkerTask.java:175)
at org.apache.kafka.connect.runtime.WorkerTask.run(WorkerTask.java:219)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)

Vous pouvez voir d'ici qu'il y a deux problèmes liés :


  • Error retrieving Avro schema for id 7

  • Subject not found.; error code: 40401


Ce qui me dérange, c'est que j'ai spécifié que la stratégie est RecordNameStrategy qui, je pense, devrait utiliser l'octet magique pour aller chercher le schéma par opposition au nom du sujet, mais il y a des erreurs sur le sujet introuvable. Je ne sais pas s'il s'agit réellement de rechercher un nom de sujet ou d'obtenir un schéma par l'ID. Quoi qu'il en soit, en ssh-ing à l'instance de connexion et en faisant une boucle pour
http://schema-registry-service:8081/schemas/ids/7obtenir le schéma renvoyé. Il y a une journalisation supplémentaire au-dessus de cette trace de pile qui semble décevante comme si elle utilisait toujours la mauvaise stratégie de nom :

INFO AvroConverterConfig values:
schema.registry.url = [http://schema-registry-service:8081]
basic.auth.user.info = [hidden]
auto.register.schemas = false
max.schemas.per.subject = 1000
basic.auth.credentials.source = URL
schema.registry.basic.auth.user.info = [hidden]
value.subject.name.strategy = class io.confluent.kafka.serializers.subject.TopicNameStrategy
key.subject.name.strategy = class io.confluent.kafka.serializers.subject.TopicNameStrategy

Quelqu'un at-il des indices sur la façon de résoudre ce problème? J'utilise les images suivantes:


  • confluentinc/cp-kafka-connect:5.2.0

  • confluentinc/cp-kafka:5.1.0


Merci


Solution du problème

Dans la trace, lookUpSubjectVersionsignifie qu'il a essayé de faire une recherche sous /subjects/:name/versionspour chaque ID répertorié là-bas, puis n'a pas pu trouver schemaId=7(Remarque : pas la version = 7), mais pas trop clair d'après les journaux ce :namequ'il essaie d'utiliser ici, mais si ce n'est pas le cas 't trouvé, alors vous obtiendrez votre Subject not founderreur. Si mon PR était accepté, le nom du sujet serait plus clair

Je pense que cela peut être dû à l'utilisation de RecordNameStrategy. En regardant le PR pour cette propriété, j'ai compris qu'il n'était vraiment testé que par rapport au code producteur/consommateur, et pas complètement dans l'API Connect. Par rapport au comportement par défaut deTopicNameStrategy

Lequel, vous pouvez voir qu'il a essayé d'utiliser

value.subject.name.strategy = class io.confluent.kafka.serializers.subject.TopicNameStrategy
key.subject.name.strategy = class io.confluent.kafka.serializers.subject.TopicNameStrategy

Mais en regardant de plus près, je pense que vous l'avez peut-être mal configuré.

Semblable à la façon dont vous avez value.converter.schema.registry.url, vous auriez en fait besoin de définir à la value.converter.value.subject.name.strategyplace.

Trouvez des lignes avec plusieurs champs en double avec Active Record, Rails et Postgres

Quelle est la meilleure façon de trouver des enregistrements avec des valeurs en double sur plusieurs colonnes à l'aide de Postgres et d'Activerecord ?

J'ai trouvé cette solution ici:

User.find(:all,:group => [:first,:email],:having => "count(*) > 1" )

Mais cela ne semble pas fonctionner avec postgres. J'obtiens cette erreur :

PG::GroupingError : ERREUR : la colonne "parts.id" doit apparaître dans la clause GROUP BY ou être utilisée dans une fonction d'agrégation


Solution du problème

Version testée et fonctionnelle

User.select(:first,:email).group(:first,:email).having("count(*) > 1")

De plus, c'est un peu sans rapport mais pratique. Si vous voulez voir combien de fois chaque combinaison a été trouvée, mettez.size à la fin :

User.select(:first,:email).group(:first,:email).having("count(*) > 1").size

et vous obtiendrez un ensemble de résultats qui ressemble à ceci :

{[nil, nil]=>512,
["Joe", "test@test.com"]=>23,
["Jim", "email2@gmail.com"]=>36,
["John", "email3@gmail.com"]=>21}

Je pensais que c'était plutôt cool et je ne l'avais jamais vu auparavant.

Merci à Taryn, ce n'est qu'une version modifiée de sa réponse.

Erreur de type non interceptée : impossible de lire les propriétés de undefined (lecture "contient")

J'essaie de créer une simple application de liste de tâches dans le cadre d'un didacticiel en ligne de DevEd, mais je suis bloqué sur une erreur apparemment déroutante.

Utilisation du balisage HTML suivant :

<div class="todo-container">
<ul class="todo-list"></ul>
</div>

.. parallèlement à du javascript pour créer et insérer des éléments de liste, j'utilise ensuite la fonction suivante pour filtrer les entrées de la liste de tâches qui ont une balise de classe spécifique.

function filterTodo(e) {
const todos = todoList.childNodes;
todos.forEach(function (todo) {
switch (e.target.value) {
case "all":
todo.style.display = "flex";
break;
case "completed":
if (todo.classList.contains("completed")) {
todo.style.display = "flex";
} else {
todo.style.display = "none";
}
break;
}
});
}

Tout ce qui précède semble bien fonctionner ensemble, jusqu'à ce que j'ajoute N'IMPORTE QUOI, même une ligne de commentaire entre les <ul></ul>balises comme ci-dessous :

<div class="todo-container">
<ul class="todo-list">
<!-- boo -->
</ul>
</div>

En faisant cela, j'obtiens l'erreur suivante lorsque j'essaie de filtrer les entrées :

Uncaught TypeError: Cannot read properties of undefined (reading 'contains')

Quelqu'un peut-il expliquer s'il vous plaît?

Code complet trouvé ici :
https://github.com/developedbyed/vanilla-todo
(pas mon référentiel)


Solution du problème

childNodesrenvoie une collection de - pour ainsi dire - nœuds enfants. Certains de ces nœuds peuvent ne pas être des éléments, mais les nœuds de texte - et les nœuds de texte n'ont aucune classListpropriété. Par example:


const childNodes = document.querySelector('.container').childNodes;
console.log(childNodes[0].classList);
console.log(childNodes[1].classList);

<div class="container">text node<span>element</span></div>

Statut ou jeton de paiement WooCommerce - comment obtenir_

Je suis novice en PHP.

J'essaie de vérifier si l'utilisateur dispose d'un jeton de paiement ou d'une autre valeur qui confirme qu'il a effectué un paiement.

Je veux rediriger la page si le statut de paiement est vide 9ils n'ont pas encore effectué de paiement).

J'ai essayé:

<?php 
if(get_post_type()=="sfwd-lessons"){
$lesson_id=get_the_ID();
}else{
$lesson_id=get_post_meta(get_the_ID(),'lesson_id',true);
}
$value = get_field( "new_field", $lesson_id );
$user_status=get_wpmg_woocommerce_payment_tokens($user_id,'token_id',true);
//$user_status='';
if(!empty($value) && empty($user_status)){
header('Location: https://xx/checkouts/checkout-page/');
exit;
?>

mais je ne pense pas que "get_wpmg_woocommerce_payment_tokens" soit un appel valide

y a-t-il un autre appel get_ que je peux faire pour vérifier si le token_id de paiement est vide pour cet utilisateur ?

ou existe-t-il un moyen sur la page de remerciement de woo commerce d'écrire un nouveau champ "payment_status" complet à user_meta_data

Merci


Solution du problème

Ce crochet woocommerce_thankyouse déclenchera chaque fois que vous actualiserez la page de remerciement.

add_action('woocommerce_thankyou', 'after_order_placed', 10, 1);
function after_order_placed($order_id) {
if (!$order_id)
return;
$order = wc_get_order($order_id);
if ($order->get_date_paid()) {
// Order is paid - Do something
} else {
// Order is NOT paid - Do something else
}
}

Le meilleur crochet pour envoyer des données à un tiers lorsque le paiement de la commande est terminé est woocommerce_payment_complete.

add_action('woocommerce_payment_complete', 'after_payment_complete');
function payment_complete_callback($order_id) {
if (!$order_id)
return;
$order = wc_get_order($order_id);
if ($order->get_date_paid()) {
// Order is paid - Do something
} else {
// Order is NOT paid - Do something else
}
}

Collection Java comme c# KeyedColllection<TKey,TItem>

Existe-t-il une collection Java qui a le même comportement que la classe abstraite KeyedCollection c# (c'est-à-dire que les éléments peuvent être récupérés à la fois par la clé et l'index) ? J'ai cherché mais je n'ai rien trouvé de similaire.

Merci, Nick


Solution du problème

Je pense que vous pouvez développer votre propre classe en étendant un HashMap



MySQL parallel execution for date range count() query do not give performance optimization

DB:

MySQL 5.7

Table Engine:

ENGINE=InnoDB

Query:

SELECT count(*) as COUNT
FROM Data d
WHERE d.StartDate >=?
AND d.StartDate <?
AND d.EntityID IN (1245)
AND d.Condition01 > 0
AND d.Condition02 = 'abs'
AND (d.Condition03 LIKE '%abs%' OR p.Condition04 LIKE '%abs%');

Parameters:

String start = "2021-12-01 00:00:00";
String end = "2022-04-01 00:00:00";

On a 200+ millions of rows query executes 20 seconds.

If start and date range divide to smaller periods, for example:

2021-12-01 00:00:00 2021-12-02 00:00:00
2021-12-02 00:00:00 2021-12-03 00:00:00
...
2022-03-30 00:00:00 2022-03-31 00:00:00
2022-03-31 00:00:00 2022-04-01 00:00:00

and execute queries with this parameters in parallel results will be obtained in 2 seconds.

Approach works well on Server with MySQL 5.6 but does not work on Server with MySQL 5.7.

Is it MySQL inner optimization or can be something else?
Can TABLE LOCK cause problem?
What else can cause the same long execution for count queries in parallel execution as for one query with big date range?


Solution of the problem

For that query, this is likely to be optimal:

INDEX(Condition02, EntityID, StartDate)

We could discuss a potentially faster approach using Summary Tables, but first, tell us some details about the selectivity of each column.

Comment puis-je faire en sorte qu'ASP.NET AJAX envoie sa réponse JSON avec compression GZip ?

J'ai activé la compression dans IIS7 et cela fonctionne comme prévu sur toutes les réponses à l'exception de celles construites par ASP.NET AJAX. J'ai un service Web qui fournit des données au client. Lorsque le service Web est appelé directement, il est correctement compressé. Cependant, lorsqu'elle est appelée via ASP.NET AJAX, la réponse JSON n'est pas compressée.

Comment puis-je faire en sorte qu'ASP.NET AJAX envoie sa réponse JSON avec compression GZip?


Solution du problème

IIS7 utilise le codage de contenu pour décider de compresser ou non la réponse (en supposant bien sûr que le navigateur accepte gzip). Ils sont définis dans applicationHost.config, et par défaut la liste est

<dynamicTypes>
<add mimeType="text/*" enabled="true" />
<add mimeType="message/*" enabled="true" />
<add mimeType="application/x-javascript" enabled="true" />
<add mimeType="*/*" enabled="false" />
</dynamicTypes>

Si vous appelez directement le service Web, la réponse XML a un type de contenu text/xml, qui est compressé. Lorsqu'elle est appelée par AJAX, la réponse JSON a un type de contenu application/json, elle n'est donc pas compressée. L'ajout de ce qui suit à applicationHost.config devrait résoudre ce problème...

 <add mimeType="application/json" enabled="true" />

SonarQube - comment désactiver la règle héritée dans le profil de qualité ?

En utilisant SonarQube, nous souhaitons créer un nouveau profil de qualité à partir d'un profil existant, mais désactiver quelques règles. L'interface graphique nous permet de modifier la sévérité des règles héritées, mais pas de désactiver les règles.

Y'a-t-il une quelconque façon de réussir cela?

Une solution de contournement consiste à copier le profil et à le modifier, mais nous souhaitons conserver le lien vers le profil d'origine afin que notre profil hérité récupère toutes les modifications apportées au profil d'origine.


Solution du problème

Indépendamment du profil utilisé, vous pouvez toujours ignorer les règles au niveau du projet: Allez dans le menu Administration --> Paramètres généraux du projet. À partir de là, accédez à Analysis Scope --> Issues.

Ajoutez la ou les règles que vous souhaitez ignorer à la liste Ignorer les problèmes sur plusieurs critères avec **comme modèle de chemin de fichier.

Comment avoir une instanciation de modèle de fonction spécifique à TU ?

Disons:


  • Certains en-têtes h.hppdéfinissent une fonction de modèle en f()utilisant sizeofson paramètre de modèle.

  • Deux fichiers source C++ différents, a.cppet b.cpp, définissent leur propre structure portant le même nom S.

  • Les deux a.cppet b.cpputiliser f()avec leurs propres S.


En d'autres termes:

h.hpp:

template <typename T>
int f()
{
return something + sizeof(T);
}

a.cpp:

#include "h.hpp"
struct S {
int a;
int b;
};
int aFunc()
{
return f<S>();
}

b.cpp:

#include "h.hpp"
struct S {
int w;
int x;
int y;
int z;
};
int bFunc()
{
return f<S>();
}

Ici, dans le même programme, les deux aFunc()et bFunc()renvoient la même valeur. En effet, les deux structures sont nommées Set une seule instanciation de fonction modèle est conservée.

Mes solutions de travail jusqu'à présent sont:

  • Nommez les structures différemment.

  • Faire f() static.

  • Faire f()partie d'un espace de noms anonyme.

  • Intégrez les deux structures à leur propre espace de noms anonyme.

  • Pouvez-vous penser à autre chose pour éviter ce problème qui ne se manifeste qu'au moment de l'exécution ?


    Solution du problème

    Si vous ne vous souciez que de la taille de S, vous pouvez l'envelopper dans un type au nom unique qui a la même taille que S, par exemple un lambda (de capture):

    // a.cpp
    void aFunc()
    {
    static auto const l = [s=S{}] {};
    f<decltype(l)>();
    }
    // b.cpp
    void bFunc()
    {
    static auto const l = [s=S{}] {};
    f<decltype(l)>();
    }

    Je crois que cette solution est pire que les quatre que vous proposez mais accomplit ce que vous voulez. Ma solution préférée serait:

  • Intégrez les deux structures à leur propre espace de noms anonyme.
  • Stocker des séries avec différentes longueurs dans la boucle for

    Le df original est comme ci-dessous:

    Hour Count
    0 15
    0 0
    0 0
    0 17
    0 18
    0 12
    1 55
    1 0
    1 0
    1 0
    1 53
    1 51
    ...

    Je parcourais ce df heure par heure et supprimais Count = 0 à cette heure, puis dessinais une boîte à moustaches de Count à cette heure. Ensuite, je me suis retrouvé avec 24 graphiques.

    Puis-je mettre ces 24 boîtes à moustaches sur le même graphique lors d'une boucle? Par exemple, obtenir une sortie df2 comme ci-dessous et utiliser plt.boxplot(df2), mais je ne sais pas si cela provoquera une erreur.

     Hour=0 Hour=1...
    0 15 55
    1 17 53
    2 18 51
    3 12 Nan

    Une autre chose est qu'après avoir supprimé 0, chaque heure a une longueur de données différente dans Count. Comment ajouter ces données et obtenir un df2 comme ci-dessus ?

    Vous pouvez utiliser le code ci-dessous pour df d'origine :

    df = pd.DataFrame({
    'Hour': {0:1, 1:1, 2:1, 3:1, 4:1, 5:1, 6:2, 7:2, 8:2, 9:2, 10:2, 11:2},
    'Count': {0:15, 1:0, 2:0, 3:17, 4:18, 5:12, 6:55, 7:0, 8:0, 9:0, 10:53, 11:51}})

    Voici le code pour créer des boîtes à moustaches horaires :

    for i in range(2):
    table1 = df[df['Hour'] == i]
    table2 = table1[table1['large_cnt']!= 0]
    fig = plt.figure(1, figsize=(9, 6))
    plt.boxplot(table2['large_cnt'])
    plt.show()


    Solution du problème

    Une option consiste à pivotfiltrer le DataFrame et à tracerboxplot :

    df.query('Count!=0').assign(i=lambda x: x.groupby('Hour').cumcount()).pivot('i', 'Hour', 'Count').boxplot();

    entrez la description de l'image ici

    OpenLayers 6 DragZoom Control - comment changer la condition

    dans OL 6, je voudrais utiliser un bouton, afin qu'un utilisateur puisse cliquer pour activer un changement pour le contrôle du zoom par glissement afin qu'il soit disponible sans maintenir la touche Maj enfoncée. Dans https://openlayers.org/en/latest/apidoc/module-ol_interaction_DragZoom-DragZoom.html, il répertorie l'option 'condition' pour gérer cela. Je ne pouvais pas comprendre comment changer et définir cette condition. Des exemples comment faire cela?


    Solution du problème

    Voici mon exemple, j'espère être utile.

    Vous pouvez changer le style avec CSS ou dans votre JS.
    Code HTML:

    <style>
    .ol-dragzoom {
    border-color: red!important;
    }
    </style>
    <div id="map"></div>
    <div id="tool-zoom" class="shadow-sm">
    <a id="tool-lupa" class="text-secondary">
    <i class="icono-arg-lupa"></i>
    </a>
    </div>

    Et le code JS:

     var aplica_lupa = function(e) {
    const dragZoom = new ol.interaction.DragZoom({
    condition: ol.events.condition.always,
    })
    map.addInteraction(dragZoom);
    };
    $("#tool-lupa").on("click",function() {
    aplica_lupa();
    })

    Si vous importez des méthodes OL, évitez "ol.interaction...".
    Et si vous voulez changer le style DragZoom dans votre JS, essayez quelque chose comme ceci:


    const dragZoom = new ol.interaction.DragZoom({
    condition: ol.events.condition.always,
    style: new ol.style.Style({
    fill: new ol.style.Fill({
    color: 'rgba(255, 255, 255, 0.6)'
    }),
    stroke: new ol.style.Stroke({
    color: '#CD4D64',
    width: 3
    })
    })
    });

    Et une autre option, avec l'interaction onclick remove :

     const dragZoom = new ol.interaction.DragZoom({
    condition: ol.events.condition.always,
    })
    var aplica_lupa = function(e) {
    map.addInteraction(dragZoom);
    };
    var remueve_lupa = function(e) {
    map.removeInteraction(dragZoom);
    };
    $('#tool-lupa').bind('click', myHandlerFunction);
    var first = true;
    function myHandlerFunction(e) {
    if(first){
    document.body.style.cursor="all-scroll";
    aplica_lupa();
    }else{
    document.body.style.cursor="default";
    remueve_lupa();
    }
    first =!first;
    }

    Obtenir le résultat ipconfig avec python dans Windows

    Je suis nouveau ici et j'apprends juste python. J'ai besoin d'aide pour obtenir la bonne adresse mac de ma carte réseau dans Windows en utilisant python. J'ai essayé de chercher, et j'ai trouvé ça:

  • Python - Get mac address


  • Obtenir l'adresse MAC


  • Analyse de sortie de commande en Python


  • Analyse de la sortie 'ipconfig /all' de Windows


  • Si je lance "ipconfig /all" depuis l'invite de commande, j'obtiens ceci:

    Windows-IP-Konfiguration
    Hostname............: DESKTOP-CIRBA63
    Primäres DNS-Suffix.......:
    Knotentyp............: Hybrid
    IP-Routing aktiviert......: Nein
    WINS-Proxy aktiviert......: Nein
    Ethernet-Adapter Ethernet:
    Verbindungsspezifisches DNS-Suffix:
    Beschreibung...........: Realtek PCIe FE Family Controller
    Physische Adresse........: 32-A5-2C-0B-14-D9
    DHCP aktiviert..........: Nein
    Autokonfiguration aktiviert...: Ja
    IPv4-Adresse..........: 192.168.142.35(Bevorzugt)
    Subnetzmaske..........: 255.255.255.0
    Standardgateway.........: 192.168.142.1
    DNS-Server...........: 8.8.8.8
    8.8.4.4
    NetBIOS über TCP/IP.......: Deaktiviert
    Ethernet-Adapter Ethernet 2:
    Medienstatus...........: Medium getrennt
    Verbindungsspezifisches DNS-Suffix:
    Beschreibung...........: Norton Security Data Escort Adapter
    Physische Adresse........: 00-CE-35-1B-77-5A
    DHCP aktiviert..........: Ja
    Autokonfiguration aktiviert...: Ja
    Tunneladapter isatap.{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}:
    Medienstatus...........: Medium getrennt
    Verbindungsspezifisches DNS-Suffix:
    Beschreibung...........: Microsoft ISATAP Adapter
    Physische Adresse........: 00-00-00-00-00-00-00-A0
    DHCP aktiviert..........: Nein
    Autokonfiguration aktiviert...: Ja

    J'ai besoin d'obtenir l'adresse mac de ma carte réseau Realtek ( 32-A5-2C-0B-14-D9 ), pas celle créée par Norton ou le tunneling Windows. Python m'a donné un autre résultat d'adresse mac si j'utilise:
    "uuid.getnode() or "getmac" je pense que le meilleur moyen est d'obtenir la sortie de
    "ipconfig /all", en regardant "Realtek" sur "Beschreibung", puis d'obtenir les informations "Physische Adresse" pour obtenir ma véritable adresse mac. Comment faire cela en python sous windows? Toute aide est appréciée. Merci d'avance.


    Solution du problème

    Vous pouvez récupérer les informations de l'interface Windows à l'aide de wmic au format XML, puis convertir le xml en dict. À partir du dict résultant, vous pouvez rassembler toutes les informations nécessaires :

    def get_interfaces_with_mac_addresses(interface_name_substring=''):
    import subprocess
    import xml.etree.ElementTree
    cmd = 'wmic.exe nic'
    if interface_name_substring:
    cmd += ' where "name like \'%%%s%%\'" ' % interface_name_substring
    cmd += ' get /format:rawxml'
    DETACHED_PROCESS = 8
    xml_text = subprocess.check_output(cmd, creationflags=DETACHED_PROCESS)
    # convert xml text to xml structure
    xml_root = xml.etree.ElementTree.fromstring(xml_text)
    xml_types = dict(
    datetime=str,
    boolean=lambda x: x[0].upper() == 'T',
    uint16=int,
    uint32=int,
    uint64=int,
    string=str,
    )
    def xml_to_dict(xml_node):
    """ Convert the xml returned from wmic to a dict """
    dict_ = {}
    for child in xml_node:
    name = child.attrib['NAME']
    xml_type = xml_types[child.attrib['TYPE']]
    if child.tag == 'PROPERTY':
    if len(child):
    for value in child:
    dict_[name] = xml_type(value.text)
    elif child.tag == 'PROPERTY.ARRAY':
    if len(child):
    assert False, "This case is not dealt with"
    else:
    assert False, "This case is not dealt with"
    return dict_
    # convert the xml into a list of dict for each interface
    interfaces = [xml_to_dict(x)
    for x in xml_root.findall("./RESULTS/CIM/INSTANCE")]
    # get only the interfaces which have a mac address
    interfaces_with_mac = [
    intf for intf in interfaces if intf.get('MACAddress')]
    return interfaces_with_mac

    Cette fonction renverra une liste de dicts, les informations souhaitées peuvent être renvoyées à partir des dicts résultants :

    for intf in get_interfaces_with_mac_addresses('Realtek'):
    print intf['Name'], intf['MACAddress']

    Faire flotter la classe SQFlite en Json()

    Je travaille actuellement sur une application où l'utilisateur peut stocker localement des données sur son appareil. C'est pourquoi j'utilise le package sqflite mais je rencontre des erreurs lors de la conversion de mes données de classe en Json. Voici le message d'erreur que j'obtiens:

    Une valeur de type 'Set' ne peut pas être renvoyée par la méthode 'toJson' car elle a un type de retour de 'Map<String, Widget>'. à cause de cette ligne:

    Map<String, Widget> toJson() => {
    EntryFields.id = id,
    EntryFields.name = name,
    EntryFields.navigation = navigation,
    };

    C'est ma classe:

    import 'package:flutter/material.dart';
    const String tableFavs = 'favorites';
    class EntryFields {
    static late String id = '_id';
    static late String name = '_name';
    static late String navigation = '_navigation';
    }
    class Entries {
    final int id;
    final String name;
    final Widget navigation;
    Entries({
    required this.id,
    required this.name,
    required this.navigation,
    });
    Map<String, Widget> toJson() => {
    EntryFields.id = id,
    EntryFields.name = name,
    EntryFields.navigation = navigation,
    };
    }

    et ceci est un extrait de ma base de données:

     Future<Entries> create(Entries entries) async {
    final db = await instance.database;
    final id = await db.insert(tableFavs, entries.toJson());
    }


    Solution du problème

    vous ne pouvez pas stocker un widget dans la base de données, il devrait s'agir de Map<String, String> essayez de stocker les paramètres du widget sous forme de chaîne, pas le widget entier, vous pouvez stocker ces types double, chaîne, int, bool..

    Comment passer un crochet useState au composant parent et mettre à jour un objet ?

    J'ai un composant utilisateur et un composant InputField dans React. Je sais que mon code est faux, mais il devrait montrer ce que je prévois de faire. Au lieu d'avoir plusieurs hooks useState pour chaque propriété de l'utilisateur, je souhaite mettre à jour un objet utilisateur où un champ Input peut mettre à jour une propriété spécifique de l'objet utilisateur.

    const User = () => {
    const [user, setUser] = useState({
    name: "",
    email: "",
    });
    return (
    <>
    <InputField
    name="name"
    value={user.name}
    onChange={() => setUser({...user, name: value })}
    />
    <InputField
    name="email"
    value={user.email}
    onChange={() => setUser({...user, email: value })}
    />
    </>
    );
    };
    const InputField = ({ name, value }) => {
    const [value, setValue] = useState("");
    return (
    <input
    type="text"
    id={name}
    value={value}
    onChange={(e) => setValue(e.target.value)}
    />
    );
    };

    Je pense que ce que je fais avec l' valueaccessoire est correct, mais ce onChangen'est pas correct et c'est mon problème. Comment puis-je passer le setValueup au composant User pour qu'il mette à jour le nom ou l'email?


    Solution du problème

    Vous devez déplacer votre logique onchange vers le composant parent. Vous pouvez donc créer une fonction onchange dans le parent et la transmettre au champ de saisie. De plus, j'utiliserais simplement l'attribut de nom des cibles pour définir l'état au lieu de définir un identifiant sur l'entrée. Donc quelque chose comme ce qui suit:

    const InputField = ({ name, value, onChange }) => {
    return (
    <input
    type="text"
    name={name}
    value={value}
    onChange={onChange}
    />
    );
    };
    const User = () => {
    const [user, setUser] = useState({
    name: "",
    email: "",
    });
    const onChange = (e) => {
    setUser({
    ...user,
    [e.target.name]: e.target.value
    })
    }
    return (
    <>
    <InputField
    name="name"
    value={user.name}
    onChange={onChange}
    />
    <InputField
    name="email"
    value={user.email}
    onChange={onChange}
    />
    </>
    );
    };

    Les classes CSS Tailwind ne s'affichent pas dans la construction de Storybook

    J'essaie de construire mon livre de contes avec tailwind css. Lors de l'exécution build-storybook, les composants sont rendus avec les classes de vent arrière. Malheureusement, lorsque je construis un livre d'histoires et que j'exécute la création storybook-static, npx http-server storybook-staticles classes ne sont pas chargées dans les histoires et les composants sont affichés sans style.

    Ceci est un dépôt repro de mon projet :
    https://gitlab.com/ens.evelyn.development/storybook-issue

    C'est mon main.js:

     const path = require('path')
    module.exports = {
    "stories": [
    "../src/components/**/**/*.stories.mdx",
    "../src/components/**/**/*.stories.@(js|jsx|ts|tsx)"
    ],
    "addons": [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    {
    name: '@storybook/addon-postcss',
    options: {
    postcssLoaderOptions: {
    implementation: require('postcss'),
    },
    },
    },
    "@storybook/addon-actions",
    "storybook-tailwind-dark-mode"
    ]}

    Ma structure de projet ressemble à ceci :

    .storybook 
    src
    components
    subdir
    Button
    index.tsx
    button.stories.js
    styles
    index.css (<-- tailwindcss file)

    Tous les indices ou conseils sont très appréciés.


    Solution du problème

    Les solutions ci-dessus ne fonctionneront pas pour la version Tailwind> 3.0 en raison du compilateur JIT.

    Solution 1: Solution facile

    dans .storybook/preview.jsle fichier, ajoutez cette ligne pour compiler les fichiers CSS générés par Tailwind comme celui-ci -

    import '!style-loader!css-loader!postcss-loader!tailwindcss/tailwind.css';

    Voici tailwindcss/tailwind.cssle fichier CSS Tailwind. Écoutez, ce qui est important, c'est que je dois ajouter !postcss-loader!pour compiler le CSS généré par Tailwind.

    Vous pouvez également ajouter votre fichier scss personnalisé comme celui-ci, le cas échéant -

    import '!style-loader!css-loader!sass-loader!../src/scss/style.scss';

    Voici ../src/scss/style.scssun fichier scss personnalisé.

    Pour la plupart des gens, cela fonctionnera dans la version Tailwind> 3.0 sans aucun problème.

    Solution 2: une sorte de solution de piratage

    Créer un élément de style personnalisé dans la page d'aperçu

    import tailwindCss from '!style-loader!css-loader!postcss-loader!sass-loader!tailwindcss/tailwind.css';
    const storybookStyles = document.createElement('style');
    storybookStyles.innerHTML = tailwindCss;
    document.body.appendChild(storybookStyles);

    J'espère que cela aidera les nouveaux utilisateurs de Tailwind qui travaillent dans Tailwind supérieur à v3.0.

    vendredi 29 avril 2022

    Vous cherchez un moyen de produire directement une jolie section de code en HTML avec VIM

    Je voudrais générer, avec VIM, du joli code HTML d'extrait de code (C, python ou autres).

    Pour l'instant, je ne connais que la commande sous VIM " :TOhtml" mais le résultat me semble trop basique.

    Voici un exemple de ce que j'aimerais obtenir (avec le nombre de lignes et les coins arrondis) :

    Exemple

    Est-ce que quelqu'un connait un moyen de produire rapidement ce genre de présentation?. Même si VIM ne peut pas le faire, existe-t-il un outil qui permette de prendre la section de code brut et de générer directement du code HTML avec le CSS personnalisable nécessaire?

    MISE À JOUR 1:

    J'ai trouvé partiellement une solution en montrant d'abord les numéros de lignes avec ":%set nu" et en faisant ":TOhtml".

    J'obtiens donc par exemple l'extrait de code suivant:

    <pre id='vimCodeElement'>
    <span id="L1" class="LineNr"> 1 </span><span class="PreProc">#include </span><span class="Constant">&quot;clFFT.h&quot;</span>
    <span id="L2" class="LineNr"> 2 </span><span class="PreProc">#include </span><span class="Constant">&lt;stdio.h&gt;</span>
    <span id="L3" class="LineNr"> 3 </span><span class="PreProc">#include </span><span class="Constant">&lt;stdlib.h&gt;</span>
    <span id="L4" class="LineNr"> 4 </span><span class="PreProc">#include </span><span class="Constant">&lt;string.h&gt;</span>
    <span id="L5" class="LineNr"> 5 </span><span class="PreProc">#include </span><span class="Constant">&lt;math.h&gt;</span>

    Ensuite, j'ai mis en style CSS:

    .LineNr { color: #007399;
    -moz-user-select: -moz-none;
    -webkit-user-select: none;
    user-select: none;
    }

    Mon problème se produit lorsque je suis sur Firefox ou Chrome:

    1) Dans le premier cas (FF), si je copie depuis la page html le code, alors quand je colle dans nedit par exemple, chaque ligne est séparée d'une ligne vierge des autres.

    2) Dans le second cas (Chrome), la sélection de code est collée correctement mais les numéros de lignes apparaissent également, je pensais que " user-select: none;" pourrait empêcher ce comportement.

    Quelqu'un pourrait-il m'aider à le débugger?

    Merci

    MISE À JOUR 2:

    J'ai essayé la solution suggérée par zeppelinmais le code HTML généré par la :TOhtmlcommande " " into vimest de la forme:

    <span class="Comment">/*</span><span class="Comment"> Allocation of 2D arrays </span><span class="Comment">*/</span>
    x = malloc((size_tot_y)*<span class="Statement">sizeof</span>(<span class="Type">double</span>*));
    x0 = malloc((size_tot_y)*<span class="Statement">sizeof</span>(<span class="Type">double</span>*));
    <span class="Statement">for</span>(i=<span class="Constant">0</span>;i&lt;=size_tot_y-<span class="Constant">1</span>;i++)
    {
    x[i] = malloc((size_tot_x)*<span class="Statement">sizeof</span>(<span class="Type">double</span>));
    x0[i] = malloc((size_tot_x)*<span class="Statement">sizeof</span>(<span class="Type">double</span>));
    }

    ou une autre partie du formulaire:

    printf(<span class="Constant">&quot;Time step</span><span class="Special">\n</span><span class="Constant">&quot;</span>);
    scanf(<span class="Constant">&quot;</span><span class="Special">%lf</span><span class="Constant">&quot;</span>,&amp;dt1);
    printf(<span class="Constant">&quot;Convergence </span><span class="Special">\n</span><span class="Constant">&quot;</span>);
    scanf(<span class="Constant">&quot;</span><span class="Special">%lf</span><span class="Constant">&quot;</span>,&amp;epsilon);

    Les deux codes HTML ci-dessus n'ont pas nécessairement de <span>balise devant chaque ligne de code d'entrée.

    Ne pensez-vous pas que ma première méthode n'est pas bonne (il y a une ligne blanche lors d'un copier/coller dans un éditeur comme nedit) à cause de la présence de balises différentes sur chaque ligne, je veux dire après la première qui est toujours <span id="L1" class="LineNr"> "n-th line" </span>?

    Prenons par exemple cette ligne:

    <span id="L1" class="LineNr"> 1 </span><span class="PreProc">#include </span><span class="Constant">&quot;clFFT.h&quot;</span>

    Le problème vient-il des autres <span>balises ( <span class="PreProc">#include </span>et <span class="Constant">&quot;clFFT.h&quot;</span>)??

    Il semble que ces 2 autres balises produisent un retour chariot lorsque je copie une partie de code, cela expliquerait la ligne vide lorsque je la colle dans un éditeur de texte, n'est-ce pas?

    Salutations

    MISE À JOUR 3: Je n'ai rien trouvé de nouveau sur ma tentative de supprimer les lignes vides lorsque je copie/colle un code initialement généré par VIMcommand :TOhtml, avec un numéro de ligne pour chaque début de ligne de code. Par exemple, je vous montre à nouveau le code HTML généré:

    <pre id='vimCodeElement'>
    <span id="L1" class="LineNr"> 1 </span><span class="PreProc">#include </span><span class="Constant">&quot;clFFT.h&quot;</span>
    <span id="L2" class="LineNr"> 2 </span><span class="PreProc">#include </span><span class="Constant">&lt;stdio.h&gt;</span>
    <span id="L3" class="LineNr"> 3 </span><span class="PreProc">#include </span><span class="Constant">&lt;stdlib.h&gt;</span>
    <span id="L4" class="LineNr"> 4 </span><span class="PreProc">#include </span><span class="Constant">&lt;string.h&gt;</span>
    <span id="L5" class="LineNr"> 5 </span><span class="PreProc">#include </span><span class="Constant">&lt;math.h&gt;</span>

    Je ne veux pas que les numéros de lignes soient sélectionnés lorsque je copie/colle du code de la page. C'est pourquoi j'ai utilisé user-select: none;dans mon CSS pour la <spanbalise.

    Peut-être que la solution consiste à supprimer le retour chariot (qui semble être double une fois que je colle le code dans un éditeur de texte car il y a des lignes vides entre chaque ligne copiée du code).

    Mais je ne sais pas comment supprimer le deuxième retour chariot lorsque je sélectionne du code et que je le copie dans le tampon de texte Copier/Coller.

    J'ai trouvé une discussion intéressante sur le lien suivant mais je n'ai pas compris toutes les subtilités: https://bugzilla.mozilla.org/show_bug.cgi?id=1273836

    Si quelqu'un avait une idée ou des indices, ce serait bien de me le dire.

    Merci


    Solution du problème

    Une option consiste à utiliser highlight, et à y diriger votre tampon :

    %!highlight --style andes -I --style-infile=/tmp/custom.css -S c -l -F gnu 


    • --style andes (thème "andes")

    • --style-infile=/tmp/custom.css (ajouter des styles CSS depuis /tmp/custom.css)

    • I - est pour le style d'inclusion (CSS en ligne)

    • S - est pour la syntaxe (langue = c)

    • l - est pour les numéros de ligne

    • F - est pour le formatage ( gnuconventions)


    /tmp/custom.css (ajoute des coins arrondis)

    pre {
    padding: 10px 20px 20px;
    border: 1px solid #777;
    border-radius: 1em;
    }

    Exemple de sortie

    entrez la description de l'image ici

    Comment obtenir une liste de fichiers triés par ordre alphabétique dans Kotlin ?

    J'ai donc un tas de fichiers texte dont j'ai besoin de lire et d'imprimer dans une vue textuelle. J'utilise actuellement.list() (java.io.File) pour obtenir la liste (il génère un tableau de chaînes de noms de fichiers) des fichiers dans un répertoire donné. Je parcoure ensuite le tableau et lis le contenu un par un.

    Le problème est que je dois classer les fichiers par ordre alphabétique (les fichiers sont des journaux et je dois d'abord afficher le journal le plus récent - les noms de fichiers sont des horodatages - (par exemple 20220414221311) - AAAAMMJJHHMMSS).

    La fonction.list semble les ordonner au hasard.

    J'ai essayé de mettre les noms dans une liste, puis de les trier, mais cela n'a pas fonctionné. Quelqu'un peut-il aider?

    Voici le code sans aucune commande:

     fun ui() {
    setContentView(R.layout.activity_main)
    val dir = getExternalFilesDir(null);
    val attendancedir = File("$dir/attendance")
    var attendancelist = attendancedir.list()
    val scroll = findViewById<View>(R.id.SCROLL) as LinearLayout
    for (attendancefile in attendancelist) {
    val attendancedisplay = File("$dir/attendance/$attendancefile")
    val tv = TextView(this)
    tv.text = attendancedisplay.readText()
    scroll.addView(tv)
    }


    Solution du problème

    Si vous avez besoin de trier votre liste par ordre alphabétique, vous pouvez utiliser les opérateurs Kotlin sortWith et compareTo. Cela devrait ressembler à :

    attendancelist.sortWith { text1, text2 -> 
    text1.compareTo(text2, ignoreCase = true)
    }

    Mais si vous avez besoin d'une liste de tri en fonction de votre horodatage 'YYYYMMDDHHMMSS', je peux suggérer les étapes suivantes :

  • Convertissez votre liste de chaînes en liste de dates.

  • Trier la liste des dates.

  • Reconvertir la liste de dates en liste de chaînes (ou utiliser la liste de dates).

  • Exemple de code suivant :

    private val sdf = SimpleDateFormat("yyyyMMddHHmmss", Locale.getDefault())
    private fun ui() {
    val dir = getExternalFilesDir(null);
    val attendancedir = File("$dir/attendance")
    val attendancelist = attendancedir.list()
    val sortedList = getSortedList(attendancelist)
    // do operations with sortedList
    }
    private fun getSortedList(attendancelist: Array<out String>): List<String?> {
    return attendancelist.map { text -> // convert your string list to date list
    sdf.parse(text)
    }.sortedWith { date1, date2 -> // sort date list
    date1.compareTo(date2)
    }.map { date -> // convert date list back to string list
    date?.let { sdf.format(it) }
    }
    }

    Connexion interrompue pendant le flottement de la poignée de main

    C'est vraiment frustrant, j'ai perdu 3 jours pour s'en débarrasser, mais toujours un problème bloqué sur macos catalina version 10.15.1 et Windows 7 également. Mes deux PC affichent la même erreur. La première fois que j'ai essayé de "récupérer des packages"

    il affiche ceci '/Users/mamun/Developer/flutter/bin/flutter --no-color packages get
    Waiting for another flutter command to release the startup lock... '

    au bout de quelques instants ça s'affiche..

    '/Users/mamun/Developer/flutter/bin/flutter --no-color packages get Exécution de "flutter pub get" dans flutterx...
    Connexion terminée pendant la poignée de main

    pub get a échoué (serveur indisponible) - tentative de nouvelle tentative 1 en 1 seconde...

    Connexion interrompue pendant l'établissement de la liaison

    pub get a échoué (serveur indisponible) - tentative de nouvelle tentative 2 en 2 secondes...,

    essayé ceci En attente d'une autre commande de flottement pour libérer le verrou de démarrage

    & https://github.com/dart-lang/pub/issues/1729 également.


    Solution du problème

    Il s'agit d'un problème propre à chaque pays. Dans certains pays, vous avez cette erreur comme le Bangladesh et certains pays africains. J'ai trouvé une solution à ce problème, c'est-à-dire utiliser un logiciel VPN lorsque vous souhaitez obtenir des packages. Le logiciel VPN utilise les adresses IP d'autres pays où ce service Google fonctionne parfaitement, vous pouvez donc facilement télécharger des packages.

    Cliquez sur un bouton pour copier un texte d'une entrée dans le presse-papiers

    j'ai un bouton

    entrez la description de l'image ici

    Quand j'ai cliqué sur COPIER

    copyImageLinkText({ mouseenter, mouseleave }, e) {
    this.showCopiedText =!this.showCopiedText
    navigator.clipboard.writeText(this.imageLink)
    clearTimeout(this._timerId)
    mouseenter(e)
    this._timerId = setTimeout(() => mouseleave(e), 1000)
    },

    Cette ligne semble fonctionner parfaitement en local sur mon MacBook Pro

    navigator.clipboard.writeText(this.imageLink)

    Cela ne fonctionne pas lorsque je le construis et le déploie sur mon serveur de développement.

    TypeError : impossible de lire les propriétés de undefined (lecture de 'writeText')

    entrez la description de l'image ici


    Solution du problème

    L'utilisation de navigator.clipboardnécessite une origine sécurisée. Ainsi, si votre environnement de développement est servi via HTTP, la méthode du presse-papiers ne sera pas disponible.

    Selon les Clipboarddocs MDN : "Cette fonctionnalité est disponible uniquement dans des contextes sécurisés (HTTPS)"

    Peut-être pourriez-vous vérifier si cette méthode est disponible avec window.isSecureContextet désactiver le bouton Copier le texte en conséquence.

    Comment ignorer des caractères spécifiques dans la chaîne

    j'ai ces variables

    m1 = 'ZZZZZ'

    m2 = 'Z___Z'

    m3 = 'ZZZZZ'

    qui représentent un labyrinthe. Lorsque j'imprime ces chaînes, je veux qu'il ignore les traits de soulignement et les remplace par des espaces. Comment puis-je atteindre cet objectif?


    Solution du problème

    Vous pouvez utiliser .replace():

    Par example,

    'Z___Z'.replace('_', ' ')

    affichera :

    Z Z

    Devons-nous faire deux transitions de disposition d'image lors de la création d'une nouvelle image ?

    Lorsque je veux télécharger une image dans la mémoire locale de l'appareil, je crée d'abord une image, puis j'émets une transition de mise en page pour passer de UNDEFINED à TRANSFER DESTINATION, puis je fais une copie du tampon vers l'image. Ensuite, je passe de TRANSFER DESTINATION à la disposition de mon choix. Existe-t-il un moyen plus direct de le faire? Dans vkCmdCopyBufferToImage il y a un argument 'dstImageLayout'. J'ai fait l'erreur de penser que l'argument dit à Vulkan de faire automatiquement la transition de l'image vers cette mise en page au fur et à mesure qu'il la copie. Cela me semblerait plus efficace et plus logique, mais ce n'est pas ce que je pensais.

    Existe-t-il un moyen de le faire sans deux transitions de mise en page ? Ce n'est pas grave s'il n'y en a pas, je pense que c'est la bonne façon de le faire, je voulais juste m'en assurer.


    Solution du problème

    Vous n'êtes pas à proprement parler obligé d'effectuer deux transitions de mise en page. La GENERALmise en page peut être utilisée avec pratiquement n'importe quoi. Ainsi, vous pouvez simplement le transférer une fois, le copier et l'utiliser à partir de là.

    Cependant, cela serait inutile pour plusieurs raisons. Tout d'abord, il est raisonnable de supposer que toute transition de mise en page à partir de UNDEFINED sera un non-op en ce qui concerne le traitement GPU réel. De telles transitions suppriment conceptuellement tout le contenu de l'image, il est donc inutile que le GPU fasse quoi que ce soit sur les octets de l'image.

    Deuxièmement, pour utiliser une image dans laquelle vous avez copié, vous aurez besoin d' une sorte de synchronisation explicite entre l'opération de copie et son utilisation. Quelle que soit cette synchronisation, elle peut également inclure une transition de mise en page. Le GPU devra s'assurer que les deux ne se chevauchent pas, vous pouvez donc aussi bien lancer une transition de mise en page.

    Enfin, utiliser GENERALcomme ceci est une optimisation prématurée et doit donc être évitée à moins que vous n'ayez des données de profilage vous indiquant que les transitions de mise en page sont un problème de performances réel (ou que vous n'avez pas d'autre choix).

    Laravel interrogeant pour obtenir des données d'une table en utilisant une autre table et une entrée

    Donc, pour le contexte, 3 tables.

    tableau des emprunteurs

     protected $table = 'borrowers';
    protected $primaryKey = 'id';
    protected $fillable = ['borrower_name', 'IC', 'phone_no', 'address'];

    tableau des livres

     protected $primaryKey = 'id';
    protected $fillable = ['ISBN', 'year', 'book_title', 'author', 'publisher_name', 'category'];

    et enfin emprunter la table avec id, loaner_id, book_id, issue_date, return_date et late_return_status qui est un bool. id_emprunteur et id_livre sont des clés étrangères.

    L'utilisateur effectue également une recherche pour choisir les livres empruntés de l'emprunteur à afficher. J'ai obtenu l'ID de l'emprunteur et je l'ai stocké dans une variable $id.

    J'ai donc besoin d'interroger pour obtenir toutes les informations de la table des livres sur les livres qu'un emprunteur a empruntés + issue_date, return_date et late_return_status.

    Voici ce que j'ai essayé jusqu'à présent.

     $books_borrowed = Borrow::join('books', 'borrow.book_id', '=', 'books.id')
    ->where('borrow.borrower_id', '=', $id)
    ->get(['books.ISBN', 'books.book_title','books.year','books.author', 'books.publisher_name',
    'borrow.issue_date', 'borrow.due_date', 'borrow.late_return_status']);


    Solution du problème

    Je crois qu'il manque une autre jointure pour que les deux tables soient liées aux clés étrangères ?

    $books_borrowed = Borrow::join('books', 'borrow.book_id', '=', 'books.id')
    ->join('borrowers', 'borrow.borrower_id', '=', 'borrowers.id')
    ->where('borrow.borrower_id', '=', $id)
    ->get(['books.ISBN', 'books.book_title', 'books.year','books.author', 'books.publisher_name',
    'borrow.issue_date', 'borrow.due_date', 'borrow.late_return_status']);

    De cette façon, vous avez les 3 tables jointes :

    --------------  ----------
    borrowers.id books.id
    -------------- ----------
    | |
    | -------------------- |
    |---> borrow.borrower_id |
    borrow.book_id <------|
    --------------------

    dictionnaire imbriqué TypeError : l'objet 'NoneType' n'est pas inscriptible

    J'ai un dictionnaire - questions. la clé est un nombre et la valeur est un autre dictionnaire. voici un exemple de structure:

     questions = {
    2313: {"question": "How much is 2+2", "answers": ["3", "4", "2", "1"], "correct": 2},
    4122: {"question": "What is the capital of France?", "answers": ["Lion", "Marseille", "Paris", "Montpellier"],
    "correct": 3}
    }

    J'ai besoin d'ajouter plus de questions au dictionnaire à partir d'un fichier texte ('questions.txt') où les questions ressemblent à ceci :
    0#Quelle est la capitale des États-Unis ?#Washington DC#New York#Los Angeles#Detroit#1
    Après avoir ouvert le fichier, j'ai créé une boucle pour parcourir toutes les questions et les ajouter au dictionnaire. J'ai utilisé une fonction de mon protocole 'chatlib':

    def split_data(data, expected_fields):
    splitted = data.split('#')
    if len(splitted) == expected_fields:
    return splitted
    else:
    return

    ainsi, par exemple, lorsque je l'utilise sur la question avant de la renvoyer sous la forme d'une liste qui ressemble à ceci :
    ['0', 'Quelle est la capitale des États-Unis ?', 'Washington DC', 'New York', ' Los Angeles', 'Detroit', '1']
    J'ai essayé beaucoup de façons différentes d'écrire le code principal,

     list_new_questions = open("questions.txt").read().split('\n')
    for question in list_new_questions:
    questionlist = chatlib.split_data(question, 7)
    key = int(questionlist[0])
    questions[key] = {"question": "", "answers": [], "correct": 0}
    questions[key]["question"] = questionlist[1]
    questions[key]["answers"] = [questionlist[2], questionlist[3], questionlist[4], questionlist[5]]
    questions[key]["correct"] = int(questionlist[6])

    mais chaque fois qu'il renvoie une erreur (TypeError: l'objet 'NoneType' n'est pas inscriptible) et dit que la valeur de int(questionlist[0]) est None mais je ne comprends pas pourquoi. Comment peut-il être None, il est censé être la valeur int du premier élément de la liste questionlist qui est toujours un nombre. chaque fois que j'imprime int(questionlist[0]), il imprime toujours un nombre, donc je ne comprends pas pourquoi il dit que c'est None.


    Solution du problème

    lorsque vous revenez de la ligne 3,
    questionlist = chatlib.split_data(question, 7)votre fonction peut revenir Nonesi le len(splitted)` n'est pas == à 7.

    donc questionlist = Nonequand il n'y a pas 7 champs et puis à la ligne 4 vous essayez de prendre l'index 0 de None.

    une solution et une restructuration faciles ressembleraient à :

    def split_data(data):
    # validate data here
    splitted = data.split("#")
    # validate splitted here if you need to
    return splitted
    list_new_questions = open("questions.txt").read().split("\n")
    for question in list_new_questions:
    questionlist = chatlib.split_data(question)
    # do your validation here
    if len(questionlist) == 7:
    # try except maybe if you are unsure about the data split you get
    key = int(questionlist[0])
    questions[key] = {
    "question": questionlist[1],
    "answers": questionlist[2:6],
    "correct": int(questionlist[6)
    }
    else:
    print("Invalid question format")

    Comment coder un script pour passer à la scène suivante après avoir remporté une manche

    Comment coder un script pour passer à la scène suivante après avoir gagné une manche? que faire pour passer à la scène suivante lorsque le joueur remporte la manche et non lorsque le bouton de la souris est enfoncé. Je fais principalement référence à ce passage Voici mon code pour la commutation de scène :


    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.SceneManagement;
    public class LevelLoader: MonoBehaviour
    {
    public Animator transition;
    public float transitionTime = 1f;
    // Update is called once per frame
    void Update()
    {
    if(Input.GetMouseButtDown(0))
    {
    LoadNextLevel();
    }
    }
    public void LoadNextLevel()
    {
    StartCoroutine(LoadLevel(SceneManager.GetActiveScene().buildIndex + 1));
    }
    IEnumerator LoadLevel(int levelIndex)
    {
    transition.SetTrigger("Start");
    yield return new WaitForSeconds(transitionTime);
    SceneManager.LoadScene(levelIndex);
    }
    }

    Solution du problème

    Tout ce que vous avez à faire est d'appeler LoadNextLevel() lorsque les conditions sont remplies pour charger le niveau suivant. Je pense qu'il faut l'appeler ici:

    if (win)
    {
    yield return new WaitForSecondsRealtime(0.3f);
    LoadNextLevel();
    }

    Découpage de la sécurité des liens dans asp.net mvc

    Je voudrais montrer certains liens uniquement aux utilisateurs authentifiés dans une application Web asp.net mvc.


    • J'utilise le modèle d'une application Web asp.net mvc dans Visual Studio 2008 fourni avec la version bêta d'asp.net mvc.

    • J'utilise l'authentification par formulaire.

    • Je voudrais ajouter quelque chose comme ce qui suit à une vue existante :


    <a href="/Account/ChangePassword">Modifier le mot de passe</a>

    et n'afficher le lien qu'aux utilisateurs connectés.

    Quelle est la manière la plus simple de faire cela? Je voudrais quelque chose d'aussi simple que le découpage de sécurité du web.sitemap que j'ai essayé avec les formulaires Web asp.net. (Cela peut-il être utilisé avec mvc? Ou est-ce uniquement pour les formulaires Web?)


    Solution du problème

    Ce qui suit devrait fonctionner. Vous devrez également faire quelque chose de similaire dans l'action du contrôleur pour cela au cas où l'utilisateur entrerait l'URL à la main dans son navigateur. Ou, comme vous le dites, vous pouvez restreindre l'accès à l'action dans le fichier web.config.

     <% if (HttpContext.Current.Request.IsAuthenticated) { %>
    <a href="/Account/ChangePassword">Change password</a>
    <% } %>

    Le jeton d'URL de téléchargement du stockage Firebase expire

    est-il possible que le jeton expire dans downloadUrl du stockage firebase. Je ne peux pas accéder à mon dossier après un certain temps. Je vois accès refusé. chemin du fichier est comme:
    https://firebasestorage.googleapis.com/v0/b/m*****-dev.appspot.com/o/panel-photo?alt=media&token=fasdfjıo fjıosadf


    Solution du problème


    Les URL de téléchargement générées par les SDK Firebase n'expirent pas après un certain temps. Bien que vous puissiez révoquer manuellement leur jeton, cela n'est pas basé sur le temps.

    Si vous avez besoin d'URL offrant un accès public pendant un certain temps, consultez les URL signées que les SDK Google Cloud peuvent générer. Vous devrez cependant le faire à partir d'un serveur, car ces SDK nécessitent un accès complet à votre compartiment/projet.

    Comment comparer les packages dotnet et txt

    j'ai le script:

    $Test = (dotnet list C:\Tasks.Api.csproj package) et il fournit quelques packages (AVEC 2 ESPACES À LA FIN !) :

    Project 'Tasks.Api' has the following package references 
    [net5.0]:
    Top-level Package Requested Resolved
    > AspNetCore.HealthChecks.SqlServer 6.0.0 6.0.0
    > Microsoft.ApplicationInsights.AspNetCore 2.18.0 2.18.0
    > Microsoft.EntityFrameworkCore.Tools 5.0.11 5.0.11
    > Swashbuckle.AspNetCore 6.2.3 6.2.3
    (SPACE)
    (SPACE)

    gettype provide next:

    entrez la description de l'image ici

    Ensuite, j'ai un "bon" fichier (txt):

    AspNetCore.HealthChecks.SqlServer
    Microsoft.ApplicationInsights.AspNetCore

    Maintenant, je veux savoir si mon "bon" fichier contient des lignes de $Test ou non ?

    Je pense que j'ai essayé des millions d'autres options, mais maintenant je suis bloqué dessus:

    $whiteliste = Get-Content C:\whitelist.txt 
    $test = (dotnet list C:\Tasks.Api.csproj package)
    $array = @()
    $test[3..($test.Length-2)] | foreach {
    $array+=$_
    }
    Foreach ($item in $array) {
    Write-host "!!!" $item
    $containsWord = $whiteliste | %{$_ -contains $item.Remove(" ")}
    if ($containsWord -contains $true) {
    Write-Host "There is!"
    } else {
    Write-Host "There ins't!"
    }
    }

    Merci!


    Solution du problème

    Sans être fantaisiste, une solution simple serait d'utiliser l' -Matchopérateur pour trouver ces références de packages, car ce sont des noms uniques, et nous pouvons utiliser des RegEx conviviaux :

    $whiteliste = (Get-Content -Path "C:\whitelist.txt").Foreach{[regex]::Escape($_.Trim())} -join "|"
    $test.Foreach{
    if ($_ -match $whiteliste) {
    Write-Host -Object "Found: [$($Matches[0])]"
    }
    }

    Edit : sur la base de votre commentaire sur le message de Santi, si vous souhaitez qu'il vous indique s'il n'y a pas de correspondance trouvée, vous pouvez ajouter une clause Begin, Process et End :

    $test.ForEach{
    Begin { $Matches = $null }
    Process {
    if ($_ -match $tomatch) {
    Write-Host -Object "Found: $($Matches[0])"
    }
    }
    End {
    if ($null -eq $Matches) {
    "No Match Found:("
    }
    }
    }


    • Tout d'abord, la clause Begin définira la variable automatique de $matchesà $null; de cette façon, il n'interfère pas avec les matchs passés.

    • Ensuite, la clause Process exécutera votre code à ajouter à $matches.

    • Enfin, la clause End vérifiera si $matchesa été rempli et si ce n'est pas le cas, indique que rien n'a été trouvé.

      • Ceci est faisable car -matchremplira la $matchesvariable lorsque quelque chose sera trouvé.

      • Si rien n'est trouvé, la variable ne sera pas renseignée.



    Création de rapports pour chaque valeur unique dans la colonne dans PowerBI

    J'essaie de trouver une réponse s'il est possible d'automatiser la création de rapports PowerBI pour chaque valeur unique dans l'une des colonnes (c'est comme filtrer sur l'ensemble du rapport pour l'une des valeurs et publier le rapport que de changer la valeur à la suivante et répéter les étapes pour les autres valeurs ) ? Existe-t-il un moyen rapide de le faire? J'ai écrit un programme pour filtrer via un lien et cliquer sur la souris plutôt que d'enregistrer des liens pour que chaque personne puisse exceller, mais je me demande s'il existe un moyen plus fiable et plus rapide de le faire. J'utilise PowerBI premium pour l'utilisateur.


    Solution du problème

    Cela s'appelle généralement « Report Bursting » ou « Data Driven Subscriptions », et voici une procédure pas à pas pour le faire avec Power Automate et Power BI.

    Depuis l'intérieur d'un conteneur Docker, comment puis-je me connecter à l'hôte local de la machine ?

    J'ai donc un Nginx qui s'exécute dans un conteneur docker, j'ai un mysql qui s'exécute sur localhost, je veux me connecter à MySql depuis mon Nginx. Le MySql s'exécute sur localhost et n'expose pas un port au monde extérieur, donc il est lié à localhost, pas lié à l'adresse IP de la machine.

    Existe-t-il un moyen de se connecter à ce MySql ou à tout autre programme sur localhost à partir de ce conteneur docker ?

    Cette question est différente de "Comment obtenir l'adresse IP de l'hôte Docker à partir d'un conteneur Docker" en raison du fait que l'adresse IP de l'hôte Docker peut être l'adresse IP publique ou l'adresse IP privée du réseau qui peut ou peut ne pas être accessible depuis le conteneur Docker (je veux dire une adresse IP publique si elle est hébergée chez AWS ou quelque chose comme ça). Même si vous avez l'adresse IP de l'hôte Docker, cela ne signifie pas que vous pouvez vous connecter à l'hôte Docker depuis le conteneur étant donné que l'adresse IP car votre réseau Docker peut être superposé, hôte, pont, macvlan, aucun, etc., ce qui limite l'accessibilité de cette adresse IP.


    Solution du problème

    Modifier:

    Si vous utilisez Docker-for-mac ou Docker-for-Windows 18.03+, connectez-vous simplement à votre service mysql en utilisant l'hôte host.docker.internal(au lieu de 127.0.0.1dans votre chaîne de connexion).

    Si vous utilisez Docker-for-Linux 20.10.0+, vous pouvez également utiliser l'hôte host.docker.internal si vous avez démarré votre conteneur Docker avec l' --add-host host.docker.internal:host-gatewayoption.

    Sinon, lisez ci-dessous

    TLDR

    Utilisez --network="host"dans votre docker runcommande, puis 127.0.0.1dans votre conteneur docker pointera vers votre hôte docker.

    Remarque : Ce mode ne fonctionne que sur Docker pour Linux, conformément à la documentation.

    Remarque sur les modes de mise en réseau du conteneur Docker

    Docker propose différents modes de mise en réseau lors de l'exécution de conteneurs. Selon le mode que vous choisissez, vous vous connecterez différemment à votre base de données MySQL exécutée sur l'hôte Docker.

    docker run --network="bridge" (par défaut)

    Docker crée un pont nommé docker0par défaut. L'hôte Docker et les conteneurs Docker ont tous deux une adresse IP sur ce pont.

    sur l'hôte Docker, tapez sudo ip addr show docker0vous aurez une sortie ressemblant à :

    [vagrant@docker:~] $ sudo ip addr show docker0
    4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 56:84:7a:fe:97:99 brd ff:ff:ff:ff:ff:ff
    inet 172.17.42.1/16 scope global docker0
    valid_lft forever preferred_lft forever
    inet6 fe80::5484:7aff:fefe:9799/64 scope link
    valid_lft forever preferred_lft forever

    Donc, ici, mon hôte docker a l'adresse IP 172.17.42.1sur l' docker0interface réseau.

    Démarrez maintenant un nouveau conteneur et obtenez un shell dessus : docker run --rm -it ubuntu:trusty bashet dans le type de conteneur ip addr show eth0pour découvrir comment son interface réseau principale est configurée :

    root@e77f6a1b3740:/# ip addr show eth0
    863: eth0: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 66:32:13:f0:f1:e3 brd ff:ff:ff:ff:ff:ff
    inet 172.17.1.192/16 scope global eth0
    valid_lft forever preferred_lft forever
    inet6 fe80::6432:13ff:fef0:f1e3/64 scope link
    valid_lft forever preferred_lft forever

    Ici, mon conteneur a l'adresse IP 172.17.1.192. Regardez maintenant la table de routage :

    root@e77f6a1b3740:/# route
    Kernel IP routing table
    Destination Gateway Genmask Flags Metric Ref Use Iface
    default 172.17.42.1 0.0.0.0 UG 0 0 0 eth0
    172.17.0.0 * 255.255.0.0 U 0 0 0 eth0

    Ainsi, l'adresse IP de l'hôte Docker 172.17.42.1est définie comme route par défaut et est accessible depuis votre conteneur.

    root@e77f6a1b3740:/# ping 172.17.42.1
    PING 172.17.42.1 (172.17.42.1) 56(84) bytes of data.
    64 bytes from 172.17.42.1: icmp_seq=1 ttl=64 time=0.070 ms
    64 bytes from 172.17.42.1: icmp_seq=2 ttl=64 time=0.201 ms
    64 bytes from 172.17.42.1: icmp_seq=3 ttl=64 time=0.116 ms

    docker run --network="host"

    Vous pouvez également exécuter un conteneur Docker avec les paramètres réseau définis surhost. Un tel conteneur partagera la pile réseau avec l'hôte docker et du point de vue du conteneur, localhost(ou 127.0.0.1) fera référence à l'hôte docker.

    Sachez que tout port ouvert dans votre conteneur Docker sera ouvert sur l'hôte Docker. Et ceci sans nécessiter l' option -pou-P docker run.

    Configuration IP sur mon hôte docker :

    [vagrant@docker:~] $ ip addr show eth0
    2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:98:dc:aa brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
    valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fe98:dcaa/64 scope link
    valid_lft forever preferred_lft forever

    et depuis un conteneur docker en mode hôte :

    [vagrant@docker:~] $ docker run --rm -it --network=host ubuntu:trusty ip addr show eth0
    2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:98:dc:aa brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
    valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fe98:dcaa/64 scope link
    valid_lft forever preferred_lft forever

    Comme vous pouvez le voir, l'hôte Docker et le conteneur Docker partagent exactement la même interface réseau et ont donc la même adresse IP.

    Connexion à MySQL à partir de conteneurs

    mode pont

    Pour accéder à MySQL exécuté sur l'hôte docker à partir de conteneurs en mode pont, vous devez vous assurer que le service MySQL écoute les connexions sur l' 172.17.42.1adresse IP.

    Pour ce faire, assurez-vous d'avoir bind-address = 172.17.42.1ou bind-address = 0.0.0.0dans votre fichier de configuration MySQL (my.cnf).

    Si vous avez besoin de définir une variable d'environnement avec l'adresse IP de la passerelle, vous pouvez exécuter le code suivant dans un conteneur:

    export DOCKER_HOST_IP=$(route -n | awk '/UG[ \t]/{print $2}')

    puis dans votre application, utilisez la DOCKER_HOST_IPvariable d'environnement pour ouvrir la connexion à MySQL.

    Remarque: si vous utilisez bind-address = 0.0.0.0votre serveur MySQL, il écoutera les connexions sur toutes les interfaces réseau. Cela signifie que votre serveur MySQL est accessible depuis Internet; assurez-vous de configurer les règles de pare-feu en conséquence.

    Remarque 2 : si vous utilisez bind-address = 172.17.42.1votre serveur MySQL, il n'écoutera pas les connexions établies avec 127.0.0.1. Les processus s'exécutant sur l'hôte docker qui voudraient se connecter à MySQL devraient utiliser l' 172.17.42.1adresse IP.

    mode hôte

    Pour accéder à MySQL en cours d'exécution sur l'hôte docker à partir de conteneurs en mode hôte, vous pouvez conserver bind-address = 127.0.0.1votre configuration MySQL et tout ce que vous avez à faire est de vous connecter à 127.0.0.1partir de vos conteneurs :

    [vagrant@docker:~] $ docker run --rm -it --network=host mysql mysql -h 127.0.0.1 -uroot -p
    Enter password:
    Welcome to the MySQL monitor. Commands end with; or \g.
    Your MySQL connection id is 36
    Server version: 5.5.41-0ubuntu0.14.04.1 (Ubuntu)
    Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
    Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners.
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    mysql>

    note: utilisez mysql -h 127.0.0.1et non mysql -h localhost; sinon le client MySQL essaierait de se connecter en utilisant un socket unix.

    Modèle d'éditeur pour un problème de champ datetime (perd sa valeur sur POST)

    J'essaie de créer un modèle d'éditeur pour un champ DateTime. L'affichage du champ fonctionne comme il se doit, mais lorsque le champ est affiché en haut du serveur, il perd sa valeur. J'utilise flatpickr pour la partie date et la partie heure.

    Ma classe:

    public class myClass
    {
    [Key]
    public int Id { get; set; }
    [UIHint("DateTime")]
    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy-MM-dd HH:mm}")]
    [DataType(DataType.DateTime)]
    public DateTime MyDateTime { get; set; }
    }

    Manette:

    public ActionResult Edit()
    {
    var myClass = new myClass
    {
    Id = 1,
    MyDateTime = DateTime.Now,
    };
    ViewBag.Language = "en-US"; // "fr-FR"; //
    ViewBag.MinDate = new DateTime(2022, 4, 1, 0, 0, 0).Date.ToString("yyyy-MM-dd");
    ViewBag.MaxDate = DateTime.Today.Date.ToString("yyyy-MM-dd");
    return View("Edit2", myClass);
    }

    Voir:

    @model EditorTemplates.Models.myClass
    @{
    ViewBag.Title = "Edit2";
    }
    <h2>Edit2</h2>
    @using (Html.BeginForm("Edit", "Home", FormMethod.Post))
    {
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
    <h4>myClass</h4>
    <hr />
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    @Html.HiddenFor(model => model.Id)
    <div class="form-group">
    @Html.LabelFor(model => model.MyDateTime, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
    @Html.EditorFor(model => model.MyDateTime, new { htmlAttributes = new { @class = "form-control" } })
    @Html.ValidationMessageFor(model => model.MyDateTime, "", new { @class = "text-danger" })
    </div>
    </div>
    <div class="form-group">
    <div class="col-md-offset-2 col-md-10">
    <input type="submit" value="Save" class="btn btn-default" />
    </div>
    </div>
    </div>
    }
    <div>
    @Html.ActionLink("Back to List", "Index")
    </div>

    Modèle d'éditeur (DateTime.cshtml)

    @* usage: @Html.EditorFor(m => m.BirthDate, new { Language = 'fr-FR', MinDate = '2022-04-01', MaxDate = '2022-04-05' }) *@
    @model System.DateTime
    @{
    //var value = Model.ToString("yyyy-MM-dd [HH:mm]");
    var yearPart = Model.Year.ToString("0000");
    var monthPart = Model.Month.ToString("00");
    var dayPart = Model.Day.ToString("00");
    var datePart = $"{yearPart}-{monthPart}-{dayPart}";
    var hourPart = Model.Hour.ToString("00");
    var minutePart = Model.Minute.ToString("00");
    const string secondPart = "00";
    var timePart = $"{hourPart}:{minutePart}";
    Console.WriteLine($"{datePart} [{hourPart}:{minutePart}:{secondPart}]");
    }
    <div class="input-group" style="width: 320px">

    @Html.TextBox("date", datePart, new { @class = "form-control", @style = "min-width:220px", @id = "DatePart" })
    ^__i class="far fa-clock fa-1x" aria-hidden="true">
    @Html.TextBox("time", timePart, new { @class = "form-control", @style = "min-width:80px; max-width:80px", @id = "TimePart" })
    </div>
    @Html.TextBox("value", Model, new { @id = "Value", @class = "form-control", @readonly ="readonly" })
    <script type="text/javascript">
    let locale = '@ViewBag.Language';
    let altFormat = 'F j, Y';
    if (locale === 'fr-FR') altFormat = 'j F Y';
    flatpickr('#DatePart',
    {
    altFormat: altFormat, // Exactly the same as date format, but for the altInput field
    altInput: true, // Show the user a readable date (as per altFormat), but return something totally different to the server.
    allowInput: true,
    allowInvalidPreload: true, // Allows the preloading of an invalid date. When disabled, the field will be cleared if the provided date is invalid
    dateFormat: 'Y-m-d',
    enableTime: false,
    locale: '@ViewBag.Language',
    minDate: '@ViewBag.MinDate',
    maxDate: '@ViewBag.MaxDate',
    onChange: function (selectedDates, dateStr, instance) {
    console.log("onChange flatpickr date");
    set();
    }
    });
    flatpickr('#TimePart',
    {
    allowInput: true,
    enableTime: true,
    noCalendar: true,
    dateFormat: "H:i",
    time_24hr: true,
    onChange: function (selectedDates, dateStr, instance) {
    console.log("onChange flatpickr time");
    set();
    }
    });
    function set() {
    let dmy = document.getElementById('DatePart').value;
    console.log(`DatePart: ${dmy}`);
    // remove time part
    if (dmy.split(' ').length > 1) dmy = dmy.split(' ')[0];
    //console.log(dmy);
    let sep = '-';
    if (dmy.split(sep).length!== 3) sep = '/';
    const year = dmy.split(sep)[0];
    const month = dmy.split(sep)[1];
    const day = dmy.split(sep)[2];
    //console.log(`${year}/${month}/${day}`);
    //let hour = document.getElementById('HourPart').value;
    //if (hour.length === 1) hour = `0${hour}`;
    //let min = document.getElementById('MinutePart').value;
    //if (min.length === 1) min = `0${min}`;
    //console.log(`set: ${dmy} [${hour}:${min}]`);
    const hm = document.getElementById('TimePart').value;
    console.log(`TimePart: ${hm}`);
    sep = ':';
    const hour = hm.split(sep)[0];
    const min = hm.split(sep)[1];
    console.log(`Year: ${parseInt(year)}`);
    console.log(`Month: ${parseInt(month)}`);
    console.log(`Day: ${parseInt(day)}`);
    console.log(`Hour: ${parseInt(hour)}`);
    console.log(`Minute: ${parseInt(min)}`);
    const dt = (`${year}-${month}-${day}`);
    console.log(`date: ${dt}`);
    const tm = (`${hour}:${min}`);
    console.log(`time: ${tm}`);
    const dtm = (`${month}/${day}/${year} ${hour}:${min}:00`);
    console.log(`dtm: ${dtm}`);
    const date = new Date(parseInt(year), parseInt(month)-1, parseInt(day), parseInt(hour), min);
    console.log(`js date:${date}`);
    document.getElementById("DatePart").value = dt;
    //console.log(date.getHours() + ":" + date.getMinutes());
    document.getElementById("TimePart").value = tm;
    document.getElementById("Value").value = dtm;
    };
    </script>

    J'ai essayé plusieurs choses, mais à chaque fois la date est affichée sur le contrôleur en tant que 1er janvier 0001, [00:00].


    Solution du problème

    Le problème était que le modèle lui-même n'était pas stocké dans le modèle de l'éditeur :

    une fois que j'ai remplacé:

    @Html.TextBox("value", Model, new { @id = "Value", @class = "form-control", @readonly ="readonly" })

    by

    @Html.HiddenFor(model => model, new { @id = @dateTimeId, @class = "form-control", @readonly = "readonly" })

    J'ai récupéré la valeur pour le DateTime...

    jQuery hasClass() - vérifie plusieurs classes

    Avec:

    if(element.hasClass("class"))

    Je peux vérifier une classe, mais existe-t-il un moyen simple de vérifier si "element" a l'une des nombreuses classes?

    J'utilise:

    if(element.hasClass("class") || element.hasClass("class")... )

    Ce qui n'est pas trop mal, mais je pense à quelque chose comme:

    if(element.hasClass("class", "class2")

    Ce qui malheureusement ne fonctionne pas.

    Y a-t-il quelque chose comme ça?


    Solution du problème

    element.is('.class1,.class2')

    fonctionne, mais il est 35 % plus lent que

    element.hasClass('class1') || element.hasClass('class2')

    Graphique JSperf montrant que.hasClass() est plus rapide que.is()

    Voir aussi ce test jsbench.me.

    jeudi 28 avril 2022

    Comment puis-je supprimer les valeurs doubles supplémentaires indésirables de la minuterie

    j'ai le résultat de durée suivant

    0:00:01.110000

    et j'essaie de le faire ressembler à ce qui suit, un pour les minutes et un pour les secondes.. minutes à un chiffre puisque mon cas ne nécessite pas plus de 9 minutes

    0:01 

    le problème je ne peux pas contrôler la source de la durée car il provient du plugin que j'utilise, et je dois le gérer dans le Textwidget avec le patron précédent

    duration myResulDuration = 0:00:01.110000;
    Text(myResulDuration.toString()),
    outouts: 0:00:01.110000
    wanted result is 0:01

    Comment puis-je réussir avec ça?


    Solution du problème

    Écrire une fonction qui donne deux chiffres de données formatées

    String twoDigits(int n) => n.toString().padLeft(2, '0');

    final minutes = twoDigits(myResultTimer.inMinutes.remainder(60));
    final seconds = twoDigits(myResultTimer.inSeconds.remainder(60));

    afficher ces minutes et secondes dans le widget texte

    Text(''$minutes:$seconds')

    Provisionner l'abonnement dans checkout.session.completed pour le premier paiement

    Lorsque je crée une session de paiement, j'inclus le user_id dans les métadonnées. Cela me permet de récupérer l'user_id lorsque l' checkout.session.completedévénement est déclenché, dont j'aurai besoin pour enregistrer l'identifiant client Stripe dans la base de données pour cet utilisateur.

    Est-ce la bonne approche?

    Le problème que j'ai maintenant, c'est que compte tenu de cette logique, chaque fois que le premier paiement est créé, je devrai provisionner l'abonnement dans l' checkout.session.completedévénement, les paiements futurs seront traités par invoice.paidévénement. En effet invoice.paid, Will ne peut reconnaître l'utilisateur que par son identifiant client, qui est rempli par checkout.session.completed.

    Question:


    • Mon approche pour stocker l'identifiant client est-elle correcte ?

    • Comment puis-je provisionner l'abonnement à partir de l' checkout.session.completedévénement pour le premier paiement, puis les futurs paiements sont provisionnés par invoice.paid?



    Solution du problème

    Pour provisionner et surveiller un abonnement, Stripe recommande d'écouter trois événements: checkout.session.completed, invoice.paidet invoice.payment_failed.

    Si vous avez besoin d'un user_idpour provisionner l'abonnement, alors oui, l'ajouter aux métadonnées de la session de paiement est logique.

    Lorsque vous obtenez l' invoice.paidévénement, vous pouvez récupérer l'abonnement associé à la subscriptionpropriété de la facture. Et puis, si nécessaire, vous pouvez trouver la session de paiement pour cet abonnement avec le point de terminaison des sessions de paiement de liste et en transmettant l'ID d'abonnement.

    Remplir Spring @Value pendant le test unitaire

    J'essaie d'écrire un test unitaire pour un haricot simple utilisé dans mon programme pour valider les formulaires. Le bean est annoté avec @Componentet a une variable de classe qui est initialisée en utilisant

    @Value("${this.property.value}") private String thisProperty;

    Je voudrais écrire des tests unitaires pour les méthodes de validation à l'intérieur de cette classe, cependant, si possible, je voudrais le faire sans utiliser le fichier de propriétés. Mon raisonnement derrière cela est que si la valeur que je tire du fichier de propriétés change, j'aimerais que cela n'affecte pas mon cas de test. Mon cas de test teste le code qui valide la valeur, pas la valeur elle-même.

    Existe-t-il un moyen d'utiliser du code Java dans ma classe de test pour initialiser une classe Java et remplir la propriété Spring @Value dans cette classe, puis l'utiliser pour tester?

    J'ai trouvé ce How To qui semble être proche, mais utilise toujours un fichier de propriétés. Je préférerais que tout soit du code Java.


    Solution du problème

    Depuis Spring 4.1, vous pouvez configurer des valeurs de propriété uniquement dans le code en utilisant org.springframework.test.context.TestPropertySourcedes annotations au niveau de la classe Unit Tests. Vous pouvez utiliser cette approche même pour injecter des propriétés dans des instances de bean dépendantes

    Par example

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(classes = FooTest.Config.class)
    @TestPropertySource(properties = {
    "some.bar.value=testValue",
    })
    public class FooTest {
    @Value("${some.bar.value}")
    String bar;
    @Test
    public void testValueSetup() {
    assertEquals("testValue", bar);
    }
    @Configuration
    static class Config {
    @Bean
    public static PropertySourcesPlaceholderConfigurer propertiesResolver() {
    return new PropertySourcesPlaceholderConfigurer();
    }
    }
    }

    Remarque: Il est nécessaire d'avoir une instance de org.springframework.context.support.PropertySourcesPlaceholderConfigurerdans le contexte Spring

    Edit 24-08-2017 : Si vous utilisez SpringBoot 1.4.0 et versions ultérieures, vous pouvez initialiser les tests avec @SpringBootTestet les @SpringBootConfigurationannotations. Plus d'infos ici

    Dans le cas de SpringBoot, nous avons le code suivant

    @SpringBootTest
    @SpringBootConfiguration
    @RunWith(SpringJUnit4ClassRunner.class)
    @TestPropertySource(properties = {
    "some.bar.value=testValue",
    })
    public class FooTest {
    @Value("${some.bar.value}")
    String bar;
    @Test
    public void testValueSetup() {
    assertEquals("testValue", bar);
    }
    }

    SQL presto - jointure croisée non imbriquée avec aplatissement de l'ordinanalité

    Pourquoi ma requête n'aplatit-elle pas les données comme prévu ?

    J'interroge une table où les colonnes contiennent des tableaux. Mon objectif est de démêler les éléments des tableaux pour trouver des éléments uniques et de les transformer en lignes.

    SELECT
    table1.tag_names,
    table1.tag_ids,
    rank_position
    FROM table1
    CROSS JOIN UNNEST (tag_ids, tag_names)
    WITH ORDINALITY as T (tag_ids, tag_names, rank_position)
    ORDER BY tag_ids

    Résultats:





















    tag_namestag_idsrang_position
    ["rouge", "bleu", "vert"][111, 222, 333]une
    ["rouge", "bleu", "jaune"][111, 222, 444]4

    Solution du problème

    Vous devez utiliser l'alias introduit pour les données aplaties CROSS JOIN UNNESTdans le select :

    -- sample data
    WITH dataset (tag_names, tag_ids) AS (
    VALUES (array['red', 'blue', 'green'], array[111, 222, 444])
    )
    -- query
    select T.tag_names,
    T.tag_ids,
    rank_position
    from dataset
    CROSS JOIN UNNEST (tag_ids, tag_names)
    WITH ORDINALITY as T (tag_ids, tag_names, rank_position)
    ORDER BY tag_ids

    Production:


























    tag_namestag_idsrang_position
    rouge111une
    bleu2222
    vert4443

    NPM MODULE_NOT_FOUND [fermé]

    Fermé. Cette question a besoin de détails ou de clarté. Il n'accepte pas de réponses actuellement.


    Solution du problème

    Il y a peut-être quelque chose qui ne va pas avec l'installation de Node

    rm -rf /usr/local/lib/node_modules/npm 

    puis réinstallez Node.js

    Comment utiliseriez-vous .reduce() sur des arguments au lieu d'un tableau ou d'un objet spécifique&nbsp;?

    Je veux définir une fonction.flatten qui aplatit plusieurs éléments en un seul tableau. Je sais que ce qui suit n'est pas possible, mais...