问:
Callback casting and set from another object
I just wanted to ask if my approach is wrong or one is the right way and it can be done.

In the project, I have one hal and several types of Dir based on Base.
When I create some dir I pass hal to it because each dir uses it in its own way.
Everyone also reacts in their own way to events in the hal. so I wanted to use the callback mechanism. I one moment I have only one specific controller, and I change it, delete, and create another, at this moment I must connect callback.
I create a solution with one dir type, and it's working fine.
But what path choose when I want to use a few different dir, Can I cast to base and use base in Hal something like this:

```<code>class Base;

class Hal
{
  public:
  void set_callback(void (Base::*callback)(int), Base* base)
  {
    m_callback = callback;
    m_base = base;
  }
  void fun()
  {
    (m_base->*m_callback)(some_int);
  }

  private:
  Base* m_base;
  void (Base::*m_callback)(int);
};
</code>```
```<code>#include "Hal.h"

class Base
{
  public:
  virtual void active() = 0;
  virtual void foo(int variable) = 0;
};
</code>```
```<code>class Dir : public Base
{
  public:
  Dir(Hal& hal)
  : m_hal(hal)
  {}
  void active()
  {
    auto callback = &Dir::foo;
    //add some casting?
    m_hal.set_callback(callback, this);
  }
  void foo(int variable)
  {
    // some code
  }

  private:
  Hal& m_hal;
};
</code>```

Maybe I should add a separate class for routing such callbacks? Or use a different mechanism? Unfortunately, I don't have functional lib available in this project /:

答:
Member function pointers for one class are not convertible to member function pointers of another class, even if the functions look compatible. You can approximate this conversion using a layer of abstraction, for example using a std::function<void(Base*, int)> but it cannot be achieved using a cast.

However, member function pointers respect polymorphism. The actual function being called will depend on the dynamic type of the object with which it is called.

You only need to pass &Bar::foo, which is virtual. Since it will be called with a Dir the Dir::foo override will be used.

Changing to m_hal.set_callback(&Bar::foo, this); should do what you want.

Live example : https://godbolt.org/z/fd8hsbanv

Body:
I just wanted to ask if my approach is wrong or one is the right way and it can be done.

In the project, I have one hal and several types of Dir based on Base.
When I create some dir I pass hal to it because each dir uses it in its own way.
Everyone also reacts in their own way to events in the hal. so I wanted to use the callback mechanism. I one moment I have only one specific controller, and I change it, delete, and create another, at this moment I must connect callback.
I create a solution with one dir type, and it's working fine.
But what path choose when I want to use a few different dir, Can I cast to base and use base in Hal something like this:

class Base;

class Hal
{
  public:
  void set_callback(void (Base::*callback)(int), Base* base)
  {
    m_callback = callback;
    m_base = base;
  }
  void fun()
  {
    (m_base->*m_callback)(some_int);
  }

  private:
  Base* m_base;
  void (Base::*m_callback)(int);
};

#include "Hal.h"

class Base
{
  public:
  virtual void active() = 0;
  virtual void foo(int variable) = 0;
};

class Dir : public Base
{
  public:
  Dir(Hal& hal)
  : m_hal(hal)
  {}
  void active()
  {
    auto callback = &Dir::foo;
    //add some casting?
    m_hal.set_callback(callback, this);
  }
  void foo(int variable)
  {
    // some code
  }

  private:
  Hal& m_hal;
};

Maybe I should add a separate class for routing such callbacks? Or use a different mechanism? Unfortunately, I don't have functional lib available in this project /:


来源: stackexchange

问:
Laravel Sail installing wrong PHP version
I can't figure out why Sail installs PHP 8.1 in stead of 8.0. It breaks my app for now.

This is the docker-compose.yml:

```<code># For more information: https://laravel.com/docs/sail
version: '3'
services:
    laravel.test:
        build:
            context: ./docker/8.0
            dockerfile: Dockerfile
            args:
                WWWGROUP: '${WWWGROUP}'
        image: sail-8.0/app
        extra_hosts:
            - 'host.docker.internal:host-gateway'
        ports:
            - '${APP_PORT:-80}:80'
        environment:
            WWWUSER: '${WWWUSER}'
            LARAVEL_SAIL: 1
            XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}'
            XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}'
        volumes:
            - '.:/var/www/html'
        networks:
            - sail
        depends_on:
            - mysql
            - redis

...

</code>```

and this is the Docker file: https://github.com/laravel/sail/blob/1.x/runtimes/8.0/Dockerfile

I have rebuilt the image many times but I still get this:

```<code>sail@c5f380167b79:/var/www/html$ php -v
PHP 8.1.2 (cli) (built: Jan 24 2022 10:42:51) (NTS)
</code>```

答:
It helped adding this line: RUN update-alternatives --set php /usr/bin/php8.0

https://github.com/laravel/sail/commit/dbe4a908d254d91f99ed89047c9eec4bae8973b0

ContentLicense: CC BY-SA 4.0

Body:
I can't figure out why Sail installs PHP 8.1 in stead of 8.0. It breaks my app for now.

This is the docker-compose.yml:

# For more information: https://laravel.com/docs/sail
version: '3'
services:
    laravel.test:
        build:
            context: ./docker/8.0
            dockerfile: Dockerfile
            args:
                WWWGROUP: '${WWWGROUP}'
        image: sail-8.0/app
        extra_hosts:
            - 'host.docker.internal:host-gateway'
        ports:
            - '${APP_PORT:-80}:80'
        environment:
            WWWUSER: '${WWWUSER}'
            LARAVEL_SAIL: 1
            XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}'
            XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}'
        volumes:
            - '.:/var/www/html'
        networks:
            - sail
        depends_on:
            - mysql
            - redis

...

and this is the Docker file: https://github.com/laravel/sail/blob/1.x/runtimes/8.0/Dockerfile

I have rebuilt the image many times but I still get this:

sail@c5f380167b79:/var/www/html$ php -v
PHP 8.1.2 (cli) (built: Jan 24 2022 10:42:51) (NTS)


问:
UrlLauncher( 9700): component name for mailto is null
So I know that for android version >= 30 you need to add queries in the manifest, but this didnt do the trick for me.
Im using Android Version 29. I nevertheless added these lines to my manifest.

So my manifest looks like this.

```<code> <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<queries>
    <intent>
        <action android:name="android.intent.action.VIEW" />
        <data android:scheme="https" />
    </intent>
    <intent>
        <action android:name="android.intent.action.DIAL" />
        <data android:scheme="tel" />
    </intent>
    <intent>
        <action android:name="android.intent.action.SEND" />
        <data android:mimeType="*/*" />
    </intent>
</queries>
</code>```

I managed to reproduce the error for my machine with the code bellow. Nevertheless I get this error:

I/UrlLauncher(10601): component name for mailto:?subject=&body= is null

Down below you find the code for main.dart

```<code>import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {return Scaffold(
      body: Center(
        child: ElevatedButton(
          style: ButtonStyle(
            shape: MaterialStateProperty.all<RoundedRectangleBorder>(
              RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(18.0)),
            ),
          ),
          onPressed: () => launchEmail(
            toEmail: "js",
            subject: "dm",
            message: "jd",
          ), child: Text("null"),
        ),
      ),
    );
  }

  Future launchEmail({
    required String toEmail,
    required String subject,
    required String message,
  }) async {
    final url =
        "mailto:$toEmail?subject=${Uri.encodeFull(subject)}&body=${Uri.encodeFull(message)}";
    if (await canLaunch(url)) {
      await launch(url);
    }
  }
}
</code>```

答:
By updating your API to 30 (minSdkVersion), you are restricting the devices and Android versions which can install your app.

Alternative solution: Don't call canLaunch for mailto links - use it only for http and https!

Since I have both http(s) and mailto links in my app, I use the try-catch block.

Here is the full function:

class UrlHandler {
  /// Attempts to open the given [url] in in-app browser. Returns `true` after successful opening, `false` otherwise.
  static Future<bool> open(String url) async {
    try {
      await launch(
        url,
        enableJavaScript: true,
      );
      return true;
    } catch (e) {
      log(e.toString());
      return false;
    }
  }
}
```

Body:
So I know that for android version >= 30 you need to add queries in the manifest, but this didnt do the trick for me.
Im using Android Version 29. I nevertheless added these lines to my manifest.

So my manifest looks like this.

 <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<queries>
    <intent>
        <action android:name="android.intent.action.VIEW" />
        <data android:scheme="https" />
    </intent>
    <intent>
        <action android:name="android.intent.action.DIAL" />
        <data android:scheme="tel" />
    </intent>
    <intent>
        <action android:name="android.intent.action.SEND" />
        <data android:mimeType="*/*" />
    </intent>
</queries>

I managed to reproduce the error for my machine with the code bellow. Nevertheless I get this error:

I/UrlLauncher(10601): component name for mailto:?subject=&body= is null

Down below you find the code for main.dart

import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {return Scaffold(
      body: Center(
        child: ElevatedButton(
          style: ButtonStyle(
            shape: MaterialStateProperty.all<RoundedRectangleBorder>(
              RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(18.0)),
            ),
          ),
          onPressed: () => launchEmail(
            toEmail: "js",
            subject: "dm",
            message: "jd",
          ), child: Text("null"),
        ),
      ),
    );
  }

  Future launchEmail({
    required String toEmail,
    required String subject,
    required String message,
  }) async {
    final url =
        "mailto:$toEmail?subject=${Uri.encodeFull(subject)}&body=${Uri.encodeFull(message)}";
    if (await canLaunch(url)) {
      await launch(url);
    }
  }
}


问:
Having an if statement change a string back and forth
I am trying to make a button change a string from 'Mode One:' to 'Mode Two:', and when pressed again, changed back to 'Mode One:' and so on and so forth. However when I run this, it will change the first time to 'Mode Two:' but when I press it again, it will not go back to Mode One.

Here is my code:

        Flip
```<code><script>

    let currentMode = 'Mode one:'

    flip = () => {
        if(currentMode = 'Mode one:'){
            currentMode = 'Mode Two:'
            console.log(currentMode)
        }else if(currentMode = 'Mode Two:'){
            currentMode = 'Mode one:'
            console.log(currentMode)
        }
    }

</script>
</code>```

答:
In your if statement, your are assigning a value to a variable. The value of this operation is always true. To compare two values you need the == operator:

```<code><script>

    let currentMode = 'Mode one:'

    flip = () => {
        if(currentMode == 'Mode one:'){
            currentMode = 'Mode Two:'
            console.log(currentMode)
        }else if(currentMode == 'Mode Two:'){
            currentMode = 'Mode one:'
            console.log(currentMode)
        }
    }

</script>

</code>```

Body:
In your if statement, your are assigning a value to a variable. The value of this operation is always true. To compare two values you need the == operator:

<script>

    let currentMode = 'Mode one:'

    flip = () => {
        if(currentMode == 'Mode one:'){
            currentMode = 'Mode Two:'
            console.log(currentMode)
        }else if(currentMode == 'Mode Two:'){
            currentMode = 'Mode one:'
            console.log(currentMode)
        }
    }

</script>


答:
Since you are using a single "=", that is not comparing values, it is assigning a value. You want to use "==" or "===":</p>
```<code>if(currentMode == 'Mode one:'){
   currentMode = 'Mode Two:'
   console.log(currentMode)
}else if(currentMode == 'Mode Two:'){
   currentMode = 'Mode one:'
   console.log(currentMode)
}
</code>```

Title: Having an if statement change a string back and forth

Body:
I am trying to make a button change a string from 'Mode One:' to 'Mode Two:', and when pressed again, changed back to 'Mode One:' and so on and so forth. However when I run this, it will change the first time to 'Mode Two:' but when I press it again, it will not go back to Mode One.

Here is my code:

        Flip

Body:
Since you are using a single "=", that is not comparing values, it is assigning a value. You want to use "==" or "===":

if(currentMode == 'Mode one:'){
   currentMode = 'Mode Two:'
   console.log(currentMode)
}else if(currentMode == 'Mode Two:'){
   currentMode = 'Mode one:'
   console.log(currentMode)
}


问:
What is the recommended way to obtain a list of all partitions that a ConcurrentMessageListenerContainer is currently handling
I am looking for the best/recommended way to obtain a list of partitions that a ConcurrentMessageListenerContainer is using while reading from a topic. Currently I am doing this manually, by having an implementation of ConsumerAwareRebalanceListener that is tracking assignments/revocations but I wonder whether there isn't a better/simpler way to achieve this.

The goal is to use this information within the application, so I always need an up-to-date list of partitions. Looking at the API for
ConcurrentMessageListenerContainer, I see that it is exposing
getAssignedPartitions().

A similar question has been asked here but there is no accepted answer until now.

答:
If your ConcurrentMessageListenerContainer is managed by KafkaListenerEndpointRegistry, you could use KafkaListenerEndpointRegistry  to get information about your listener containers through container's id and you could see the ContainerProperties, AssignedPartitions,... of this listener container.

Example of using KafkaListenerEndpointRegistry: https://docs.spring.io/spring-kafka/docs/current/reference/html/#pause-resume


问:
W3C CSS grammar, syntax oddities
I was having a look at the CSS syntax here and here and I was amazed to see both the token productions and the grammar littered with whitespace declarations. Normally whitespace is defined once in the lexer and skipped, never to be seen again. Ditto comments.

I imagine the orientation towards user-agents rather than true compilers is part of the motivation here, and also the requirement to proceed in the face of errors, but it still seems pretty odd.

Are real-life UAs that parse CSS really implemented according to this (these) grammars?

EDIT: reason for the question is actually the various LESS implementations. less.js doesn't understand consecutive comments, and lessc.exe doesn't understand comments inside selectors. In this respect they are not even able to parse CSS correctly, however that is defined. So I went to see what the actual grammar of CSS was and ...

答:
CSS, while similar to many programming languages, does have some rare instances where whitespace can be important.

Say we have the following base markup:

```<code><html>
    <head>
        <style type="text/css">
            .blueborder { width:200px; height:200px; border: solid 2px #00f; }
            .redborder  { width:100px; height:100px; margin:50px; border: solid 2px #f00; }
        </style>
    </head>

    <body>
        <div class="blueborder">
            <div class="redborder"></div>
        </div>
    </body>

</html>
</code>```

There's nothing special here, except a div inside of a div, with some styles on it so that you can see the difference between them.

Now lets add another class and an ID to the outer div:

```<code><div class="blueborder MyClass" id="MyDiv">
    <div class="redborder"></div>
</div>
</code>```

If I want to give a background to the outer div in the following manner:

```<code>.MyClass#MyDiv { background: #ccc; }
</code>```

...then the whitespace becomes important. The rule above does style the outer div, as it is parsed differently than the following:

```<code>.MyClass #MyDiv { background: #ccc; }
</code>```

...which does NOT style the outer div.

To see how these are parsed differently, you can look at how the selectors are tokenized:

Example1:

```<code>.MyClass#MyDiv -> DELIM IDENT HASH
</code>```

Example2:

```<code>.MyClass #MyDiv -> DELIM IDENT S HASH
</code>```

If we were to blindly ignore whitespace (as compilers usually do), we would miss this difference.

With that being said, I am not implying that this grammer is good. I also have a fair amount of experience in writing grammars, and I cringe when looking at this grammar. The easiest solution would have been to add the # and . symbols into the IDENT token and then everything else becomes much easier.

However they did not chose to do this, and the need for whitespace is an artifact of that decision.

ContentLicense: CC BY-SA 3.0

Title: W3C CSS grammar, syntax oddities

Body:
CSS, while similar to many programming languages, does have some rare instances where whitespace can be important.

Say we have the following base markup:

<html>
    <head>
        <style type="text/css">
            .blueborder { width:200px; height:200px; border: solid 2px #00f; }
            .redborder  { width:100px; height:100px; margin:50px; border: solid 2px #f00; }
        </style>
    </head>

    <body>
        <div class="blueborder">
            <div class="redborder"></div>
        </div>
    </body>

</html>

There's nothing special here, except a div inside of a div, with some styles on it so that you can see the difference between them.

Now lets add another class and an ID to the outer div:

<div class="blueborder MyClass" id="MyDiv">
    <div class="redborder"></div>
</div>

If I want to give a background to the outer div in the following manner:

.MyClass#MyDiv { background: #ccc; }

...then the whitespace becomes important. The rule above does style the outer div, as it is parsed differently than the following:

.MyClass #MyDiv { background: #ccc; }

...which does NOT style the outer div.

To see how these are parsed differently, you can look at how the selectors are tokenized:

Example1:

.MyClass#MyDiv -> DELIM IDENT HASH

Example2:

.MyClass #MyDiv -> DELIM IDENT S HASH

If we were to blindly ignore whitespace (as compilers usually do), we would miss this difference.

With that being said, I am not implying that this grammer is good. I also have a fair amount of experience in writing grammars, and I cringe when looking at this grammar. The easiest solution would have been to add the # and . symbols into the IDENT token and then everything else becomes much easier.

However they did not chose to do this, and the need for whitespace is an artifact of that decision.


问:
Unwanted automatic type conversion
The following code

```<code>"""
Gets the error cause from a pipeline execution status.

:param execution_status: is the pipeline execution status.
:type execution_status: dictionary.
:returns: the pipeline execution error cause and the name of the step.
:rtype: dictionary.
"""
def get_error_cause(execution_status):
  error_cause = "Unknown"
  error_step = "Unknown"
  steps = execution_status['Steps']
  if steps:
    for step in steps:
      if 'FailureReason' in step:
        print(str(type(step['Name'])))
        error_step = step['Name'],
        print(str(type(error_step)))
        error_cause = step['FailureReason']
        break
  else:
    error_cause = execution_status['FailureReason']
  return {
    'Step': error_step,
    'Cause': error_cause
  }
</code>```

when executed in AWS Lambda environment, is automatically converting a str into a tuple. The outputs for the two "print" methods that appear in the code are the following:

<class 'str'>

<class 'tuple'>

This is causing that when serializing the dictionary returned by the method as a JSON, instead of serializing the value of the 'Step' key as a string, it is serialized as a list:

```<code>{
  "Step": ["ConcatenateColumns"],
  "Cause": "AccessDenied"
}
</code>```

The input of the method is a JSON deserialized into a dictionary, like this:

```<code>{
    "ExecutionID": "some_execution_ID",
    "Status": "Failed",
    "ElapsedMinutes": 13.0,
    "Steps": [{
        "Name": "ConcatenateColumns",
        "Status": "Failed",
        "ElapsedMinutes": 13.0,
        "FailureReason": "AccessDenied"
    }],
    "FailureReason": "Step failure: One or multiple steps failed."
}
</code>```

答:
It's not automatic type conversion, you are defining error_step as a tuple.
Remove the comma at the end of the line:

```<code>error_step = step['Name']
</code>```

See python docs: https://docs.python.org/3/tutorial/datastructures.html#tuples-and-sequences

Title: Unwanted automatic type conversion

Body:
The following code

"""
Gets the error cause from a pipeline execution status.

:param execution_status: is the pipeline execution status.
:type execution_status: dictionary.
:returns: the pipeline execution error cause and the name of the step.
:rtype: dictionary.
"""
def get_error_cause(execution_status):
  error_cause = "Unknown"
  error_step = "Unknown"
  steps = execution_status['Steps']
  if steps:
    for step in steps:
      if 'FailureReason' in step:
        print(str(type(step['Name'])))
        error_step = step['Name'],
        print(str(type(error_step)))
        error_cause = step['FailureReason']
        break
  else:
    error_cause = execution_status['FailureReason']
  return {
    'Step': error_step,
    'Cause': error_cause
  }

when executed in AWS Lambda environment, is automatically converting a str into a tuple. The outputs for the two "print" methods that appear in the code are the following:

<class 'str'>

<class 'tuple'>

This is causing that when serializing the dictionary returned by the method as a JSON, instead of serializing the value of the 'Step' key as a string, it is serialized as a list:

{
  "Step": ["ConcatenateColumns"],
  "Cause": "AccessDenied"
}

The input of the method is a JSON deserialized into a dictionary, like this:

{
    "ExecutionID": "some_execution_ID",
    "Status": "Failed",
    "ElapsedMinutes": 13.0,
    "Steps": [{
        "Name": "ConcatenateColumns",
        "Status": "Failed",
        "ElapsedMinutes": 13.0,
        "FailureReason": "AccessDenied"
    }],
    "FailureReason": "Step failure: One or multiple steps failed."
}

Body:
It's not automatic type conversion, you are defining error_step as a tuple.
Remove the comma at the end of the line:

error_step = step['Name']

See python docs: https://docs.python.org/3/tutorial/datastructures.html#tuples-and-sequences


问:
How to annotate types in abstract base classes in python with mypy
I would like to use mypy to check python codebase.

I am having two problems when it comes to annotating AbstractBaseClasses with mypy:

How to disable NotImplemented? not callable errors when using:

```<code>class AbstractClass(ABC):

    @abstractmethod
    def get_something(self) -> List[str]:
        raise NotImplemented(f'You need to implement `get_something`!')
</code>```

The motivation here is that I would like to explicitly raise Exceptions when someone didn't implement the method.

How to have some pre-defined behaviour included in any class inherited from AbstractBaseClasses, and keep the signature intact?
I would like to keep the -> CustomClass signature for the sake of the interface

```<code>class AnotherABC(ABC):
    @abstractmethod
    def info(self) -> CustomClass:
        self.logger.info('Info called')
        pass  # Cannot create CustomClass here -> not enough information
</code>```

答:
Finally decided to:

Remove the explicit exceptions, and put docstrings instead

```<code>
    @abstractmethod
    def get_something(self) -> List[str]:
        """some small description"""
</code>```

Remove the logging from abstract base classes and moved it to the children classes. Technically it could be done also with a wrapper

Body:
I would like to use mypy to check python codebase.

I am having two problems when it comes to annotating AbstractBaseClasses with mypy:

How to disable NotImplemented? not callable errors when using:

class AbstractClass(ABC):

    @abstractmethod
    def get_something(self) -> List[str]:
        raise NotImplemented(f'You need to implement `get_something`!')

The motivation here is that I would like to explicitly raise Exceptions when someone didn't implement the method.

How to have some pre-defined behaviour included in any class inherited from AbstractBaseClasses, and keep the signature intact?
I would like to keep the -> CustomClass signature for the sake of the interface

class AnotherABC(ABC):
    @abstractmethod
    def info(self) -> CustomClass:
        self.logger.info('Info called')
        pass  # Cannot create CustomClass here -> not enough information

Body:
Finally decided to:

Remove the explicit exceptions, and put docstrings instead

    @abstractmethod
    def get_something(self) -> List[str]:
        """some small description"""

Remove the logging from abstract base classes and moved it to the children classes. Technically it could be done also with a wrapper


问:
Failed to Find Any Kerberos TGT while trying to access Kerberized HBase Without kinit
I have a very simple Scala HBase GET application.
I tried to make the connection as below:

```<code>import org.apache.hadoop.hbase.{HBaseConfiguration, TableName}
import org.apache.hadoop.hbase.client.{ConnectionFactory, Get}

object Debug extends App {
    val hbaseConf: HadoopConf = HBaseConfiguration.create
    val connection: Connection = ConnectionFactory.createConnection(hbaseConf)
    val hbaseTable = connection.getTable(TableName.valueOf("my-hbase-table"))
    hbaseTable.get(new Get("rowkey".getBytes).addColumn("colFam".getBytes,"colName".getBytes))
}
</code>```

Whenever I run this, I get an error like below:

```<code>Caused by: javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)]
at com.sun.security.sasl.gsskerb.GssKrb5Client.evaluateChallenge(GssKrb5Client.java:211)
at org.apache.hadoop.hbase.security.AbstractHBaseSaslRpcClient.getInitialResponse(AbstractHBaseSaslRpcClient.java:131)
at org.apache.hadoop.hbase.security.NettyHBaseSaslRpcClientHandler$1.run(NettyHBaseSaslRpcClientHandler.java:108)
at org.apache.hadoop.hbase.security.NettyHBaseSaslRpcClientHandler$1.run(NettyHBaseSaslRpcClientHandler.java:104)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:422)
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1746)
at org.apache.hadoop.hbase.security.NettyHBaseSaslRpcClientHandler.handlerAdded(NettyHBaseSaslRpcClientHandler.java:104)
at org.apache.hbase.thirdparty.io.netty.channel.DefaultChannelPipeline.callHandlerAdded0(DefaultChannelPipeline.java:606)
at org.apache.hbase.thirdparty.io.netty.channel.DefaultChannelPipeline.addFirst(DefaultChannelPipeline.java:187)
at org.apache.hbase.thirdparty.io.netty.channel.DefaultChannelPipeline.addFirst(DefaultChannelPipeline.java:380)
at org.apache.hbase.thirdparty.io.netty.channel.DefaultChannelPipeline.addFirst(DefaultChannelPipeline.java:359)
at org.apache.hadoop.hbase.ipc.NettyRpcConnection.saslNegotiate(NettyRpcConnection.java:200)
... 18 more
Caused by: GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)
at sun.security.jgss.krb5.Krb5InitCredential.getInstance(Krb5InitCredential.java:162)
at sun.security.jgss.krb5.Krb5MechFactory.getCredentialElement(Krb5MechFactory.java:122)
at sun.security.jgss.krb5.Krb5MechFactory.getMechanismContext(Krb5MechFactory.java:189)
at sun.security.jgss.GSSManagerImpl.getMechanismContext(GSSManagerImpl.java:224)
at sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:212)
at sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:179)
at com.sun.security.sasl.gsskerb.GssKrb5Client.evaluateChallenge(GssKrb5Client.java:192)
... 30 more

</code>```

I am using Windows, so I have put 4 files under the root directory of C: drive:

```<code>    C:\cacerts
    C:\jaas.conf
    C:\krb5.conf
    C:\principal.keytab
</code>```

My C:\jaas.conf :

```<code>KafkaClient {
    com.sun.security.auth.module.Krb5LoginModule required
    useKeyTab=true
    keyTab="C:\\principal.keytab"
    useTicketCache=false
    debug=true
    principal="principal@REALM";
};
Client {
    com.sun.security.auth.module.Krb5LoginModule required
    useKeyTab=true
    keyTab="C:\\principal.keytab"
    useTicketCache=false
    debug=true
    principal="principal@REALM";
};
com.sun.security.jgss.krb5.initiate {
    com.sun.security.auth.module.Krb5LoginModule required
    useKeyTab=true
    keyTab="C:\\principal.keytab"
    principal="principal@REALM";
};
</code>```

I am on Cloudera CDH version 6.3.2. Downloaded hbase-client-config (ssl-client.xml, hdfs-site.xml, hbase-site.xml, core-site.xml) from Cloudera manager and added HBase client config files under resources folder in IntelliJ. my-hbase-client-config-files

And also set VM options for jaas.conf in IntelliJ, Run/Debug Configurations -> Application -> Build and run -> VM Options. my-intellij-application-vm-options-config

When application is started, am able to see jaas.conf file is being taken jaas.conf-logs

Even if it is saying that it gonna use the keytab, still I am getting error like this: Kerberos-error-message

My Cloudera version: 6.3.2

Scala version: 2.11.12

HBase Client: 2.1.0

Does anyone has any ideas?
Is Java authentication system not taking Kerberos ticket by itself when I give jaas.conf?

答:
You will get this error message when Jaas cannot access the kerberos keytab.

Can you check for user permission issues?
Login as user that will run the code and do a kinit ?  What error message do you get? (Resolve the permission issue I'm suggesting you  have.)

You seem to rule out a path issue, and seem to have the correct '\\'.

Body:
I have a very simple Scala HBase GET application.
I tried to make the connection as below:

import org.apache.hadoop.hbase.{HBaseConfiguration, TableName}
import org.apache.hadoop.hbase.client.{ConnectionFactory, Get}

object Debug extends App {
    val hbaseConf: HadoopConf = HBaseConfiguration.create
    val connection: Connection = ConnectionFactory.createConnection(hbaseConf)
    val hbaseTable = connection.getTable(TableName.valueOf("my-hbase-table"))
    hbaseTable.get(new Get("rowkey".getBytes).addColumn("colFam".getBytes,"colName".getBytes))
}

Whenever I run this, I get an error like below:

Caused by: javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)]
at com.sun.security.sasl.gsskerb.GssKrb5Client.evaluateChallenge(GssKrb5Client.java:211)
at org.apache.hadoop.hbase.security.AbstractHBaseSaslRpcClient.getInitialResponse(AbstractHBaseSaslRpcClient.java:131)
at org.apache.hadoop.hbase.security.NettyHBaseSaslRpcClientHandler$1.run(NettyHBaseSaslRpcClientHandler.java:108)
at org.apache.hadoop.hbase.security.NettyHBaseSaslRpcClientHandler$1.run(NettyHBaseSaslRpcClientHandler.java:104)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:422)
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1746)
at org.apache.hadoop.hbase.security.NettyHBaseSaslRpcClientHandler.handlerAdded(NettyHBaseSaslRpcClientHandler.java:104)
at org.apache.hbase.thirdparty.io.netty.channel.DefaultChannelPipeline.callHandlerAdded0(DefaultChannelPipeline.java:606)
at org.apache.hbase.thirdparty.io.netty.channel.DefaultChannelPipeline.addFirst(DefaultChannelPipeline.java:187)
at org.apache.hbase.thirdparty.io.netty.channel.DefaultChannelPipeline.addFirst(DefaultChannelPipeline.java:380)
at org.apache.hbase.thirdparty.io.netty.channel.DefaultChannelPipeline.addFirst(DefaultChannelPipeline.java:359)
at org.apache.hadoop.hbase.ipc.NettyRpcConnection.saslNegotiate(NettyRpcConnection.java:200)
... 18 more
Caused by: GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)
at sun.security.jgss.krb5.Krb5InitCredential.getInstance(Krb5InitCredential.java:162)
at sun.security.jgss.krb5.Krb5MechFactory.getCredentialElement(Krb5MechFactory.java:122)
at sun.security.jgss.krb5.Krb5MechFactory.getMechanismContext(Krb5MechFactory.java:189)
at sun.security.jgss.GSSManagerImpl.getMechanismContext(GSSManagerImpl.java:224)
at sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:212)
at sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:179)
at com.sun.security.sasl.gsskerb.GssKrb5Client.evaluateChallenge(GssKrb5Client.java:192)
... 30 more

I am using Windows, so I have put 4 files under the root directory of C: drive:

    C:\cacerts
    C:\jaas.conf
    C:\krb5.conf
    C:\principal.keytab

My C:\jaas.conf :

KafkaClient {
    com.sun.security.auth.module.Krb5LoginModule required
    useKeyTab=true
    keyTab="C:\\principal.keytab"
    useTicketCache=false
    debug=true
    principal="principal@REALM";
};
Client {
    com.sun.security.auth.module.Krb5LoginModule required
    useKeyTab=true
    keyTab="C:\\principal.keytab"
    useTicketCache=false
    debug=true
    principal="principal@REALM";
};
com.sun.security.jgss.krb5.initiate {
    com.sun.security.auth.module.Krb5LoginModule required
    useKeyTab=true
    keyTab="C:\\principal.keytab"
    principal="principal@REALM";
};

I am on Cloudera CDH version 6.3.2. Downloaded hbase-client-config (ssl-client.xml, hdfs-site.xml, hbase-site.xml, core-site.xml) from Cloudera manager and added HBase client config files under resources folder in IntelliJ. my-hbase-client-config-files

And also set VM options for jaas.conf in IntelliJ, Run/Debug Configurations -> Application -> Build and run -> VM Options. my-intellij-application-vm-options-config

When application is started, am able to see jaas.conf file is being taken jaas.conf-logs

Even if it is saying that it gonna use the keytab, still I am getting error like this: Kerberos-error-message

My Cloudera version: 6.3.2

Scala version: 2.11.12

HBase Client: 2.1.0

Does anyone has any ideas?
Is Java authentication system not taking Kerberos ticket by itself when I give jaas.conf?


问:
How to load shell aliases in an alpine docker container with start
I have written a DOCKER file, which uses as an image an private adapted alpine image, which contains a nginx server.
Note: alpine uses zsh, not bash.

I love to have some shell aliases available, when working in the container and it drives me nuts, when they are missing. So I copy a small prepared file to /root/.profile, which works. I can view the file and it’s contents. But the file does not load only if I manually do . ~/.profile in the container then I have the aliases available.

What do I have to do, that my profile is automatically loaded after I started the container and connect into it’s shell?

```<code>FROM myprivatealpineimage/base-image-php:7.4.13

ARG TIMEZONE

COPY ./docker/shared/bashrc /root/.profile

COPY ./docker/shared/ /tmp/scripts/
RUN chmod +x -R /tmp/scripts/ \
    && /tmp/scripts/set_timezone.sh ${TIMEZONE}\
    && apk update\
    && apk add --no-cache git

RUN install-ext pecl/apcu pecl/imagick pecl/zip pecl/redis
RUN apk add --no-cache --repository http://dl-3.alpinelinux.org/alpine/edge/testing gnu-libiconv
ENV LD_PRELOAD /usr/lib/preloadable_libiconv.so php

WORKDIR /var/www
</code>```

答:
By default docker start a non-login shell.
To read .profile file you need a login shell docker exec -it <container> ash -l.

To read /etc/profile (or another startup file) everytime, you've to set ENV variable.

Example Dockerfile

```<code>ARG PHPVERSION=7.4
FROM php:$PHPVERSION-fpm-alpine

ARG PHPVERSION=7.4
ENV PHPVERSION_ENV=$PHPVERSION

# copy composer from official image
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

#set $ENV
ENV ENV=/etc/profile
#copy aliases definition
COPY /assets/alias.sh /etc/profile.d/alias.sh

</code>```

Body:
I have written a DOCKER file, which uses as an image an private adapted alpine image, which contains a nginx server.
Note: alpine uses zsh, not bash.

I love to have some shell aliases available, when working in the container and it drives me nuts, when they are missing. So I copy a small prepared file to /root/.profile, which works. I can view the file and it’s contents. But the file does not load only if I manually do . ~/.profile in the container then I have the aliases available.

What do I have to do, that my profile is automatically loaded after I started the container and connect into it’s shell?

FROM myprivatealpineimage/base-image-php:7.4.13

ARG TIMEZONE

COPY ./docker/shared/bashrc /root/.profile

COPY ./docker/shared/ /tmp/scripts/
RUN chmod +x -R /tmp/scripts/ \
    && /tmp/scripts/set_timezone.sh ${TIMEZONE}\
    && apk update\
    && apk add --no-cache git

RUN install-ext pecl/apcu pecl/imagick pecl/zip pecl/redis
RUN apk add --no-cache --repository http://dl-3.alpinelinux.org/alpine/edge/testing gnu-libiconv
ENV LD_PRELOAD /usr/lib/preloadable_libiconv.so php

WORKDIR /var/www

Body:
By default docker start a non-login shell.
To read .profile file you need a login shell docker exec -it <container> ash -l.

To read /etc/profile (or another startup file) everytime, you've to set ENV variable.

Example Dockerfile

ARG PHPVERSION=7.4
FROM php:$PHPVERSION-fpm-alpine

ARG PHPVERSION=7.4
ENV PHPVERSION_ENV=$PHPVERSION

# copy composer from official image
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

#set $ENV
ENV ENV=/etc/profile
#copy aliases definition
COPY /assets/alias.sh /etc/profile.d/alias.sh


问:
How can I set the ~/.aws/credentials on heroku?
I'm deploying my application on Heroku and I'm trying to read files from s3 buckets, but I can't find good references about how to set the ~/.aws/credentials on Heroku context;

I'm working all day on it and trying to figure out how to solve this problem

In my local environment, I'm using the following configuration to make it works:

Someone could help me on how to set these values on Heroku, please?!?!?

答:
[default]

aws_access_key_id=[yourkeyhere]

aws_secret_access_key=[yoursecretekeyhere]

[admin]

aws_access_key_id=[yourkeyhere]

aws_secret_access_key=[yoursecretekeyhere]

I have set as above and my site is working fine.


问:
Rails / MYSQL QUERY returns value even with no record?
I have a bit of code to check if a record exists in the database, but my problem is that the variable keeps returning a result even with no records ..</p>

```<code>@page_of_book = Page.where({:number => @page, :parent_id => @book_id.id}).limit(1)

if !@page_of_book
# if no page, create a new page

end
</code>```

答:
The query returns an Array. Even if you use limit you will still get an Array with 1 or 0 elements. So your test needs to be:

```<code>if @page_of_book.empty?
  ...
</code>```

Body:
I have a bit of code to check if a record exists in the database, but my problem is that the variable keeps returning a result even with no records ..

@page_of_book = Page.where({:number => @page, :parent_id => @book_id.id}).limit(1)

if !@page_of_book
# if no page, create a new page

end

Body:
The query returns an Array. Even if you use limit you will still get an Array with 1 or 0 elements. So your test needs to be:

if @page_of_book.empty?
  ...


问:
SwiftUI (macOS) how to pass a variable to a new window (WindowGroup)?
I'm trying to use the new WindowGroup to display a more complex view in a new window but somehow I can't figure out how to pass values into the view.

Until yet I was playing around with NSWindow but there I can't use the new toolbar with .toolbar{} and I'm somehow getting weird errors when using the latest swiftUI features.

In my old code I just could pass my values into the new view like usual:

.simultaneousGesture(TapGesture(count: 2).onEnded {

      var window: NSWindow!

      if nil == window {
           let serverView = serverView(content: content) // parse my struct content(name: "XServe-Test", configFile: "/FileUrl", permissions: .rootPermissions, cluster: cluster(x12, CPUMax: .cores(28), ramMax: .gb(1200)))
           window = NSWindow(
           contentRect: NSRect(x: 20, y: 20, width: 580, height: 400),
           styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
            backing: .buffered,
            defer: false)
            window.center()
            window.setFrameAutosaveName("ServerMainView")
            window.isReleasedWhenClosed = false
            window.title = content.name
            window.contentView = NSHostingView(rootView: serverView)
            window.toolbar = NSToolbar()
            window.toolbarStyle = .unifiedCompact
         }

      window.makeKeyAndOrderFront(nil)
 }
```
<p>Now I'm using in the app file:</p>
<pre class="lang-swift prettyprint-override"><code>import SwiftUI

@main
struct myApp: App {

    var body: some Scene {

        WindowGroup {
            contentView()
        }.windowStyle(HiddenTitleBarWindowStyle())
        .commands {
            SidebarCommands()
            ToolbarCommands()
        }

        // the view that should be displayed in a new window
        WindowGroup("serverView") {
            let inputContent : content = content(name: "XServe-Test", configFile: "/FileUrl", permissions: .rootPermissions, cluster: cluster(x12, CPUMax: .cores(28), ramMax: .gb(1200)))
            serverView(content: inputContent) // this is static now :(
        }.handlesExternalEvents(matching: Set(arrayLiteral: "serverView"))
}
</code>```

and the following code to open the view:

  .simultaneousGesture(TapGesture(count: 2).onEnded {

  guard let url = URL(string: "com-code-myApp://serverView") else { return }
        NSWorkspace.shared.open(url)
}
```

How do I pass the input from the tap gesture into the new view using the WindowGroup logic?

答:
I found two ways to solve this problem. I'm using the first one, because my application is file based. The second solution is based on the great Pulse git repo.

In both cases you need to register a custom URL in the Xcode project settings under:

Tragets -> yourApp -> Info -> URL Types, otherwise it won't work.

first solution:

import SwiftUI

@main
struct myApp: App {

    var body: some Scene {
        // 'default' view
        WindowGroup { contentView() }

        // the view that should open if someone opens your file
        WindowGroup("fileView") { fileView() }
        .handlesExternalEvents(matching: ["file"]) // does the magic

    }
}

struct fileView: View {
    var body: some View {
        VStack{ /* your view content */}
        .onOpenURL(perform: { url in
            // get url and read e.g.: your info file
        })
    }
}

// you can open a file using:
Button("openMyFileinAnExtraWindow"){
   let fileUrl = URL(fileURLWithPath: "~/Documents/myFile.yourExtension")
   NSWorkspace.shared.open(fileUrl)
}

```
<p>second solution:<br/></p>
<blockquote>
<p>Notice: I created this code snippet based on the great Pulse git repo.</p>
</blockquote>
<pre class="lang-swift prettyprint-override"><code>import SwiftUI

@main
struct myApp: App {

    var body: some Scene {
        // 'default' view
        WindowGroup { contentView() }

        // the view that should open if someone opens your file
        WindowGroup { DetailsView() }
        .handlesExternalEvents(matching: Set(arrayLiteral: "newWindow")) // this url must be registerd

    }
}

struct DetailsView: View {
    var body: some View {
        ExternalEvents.open
    }
}

public struct ExternalEvents {
    /// - warning: Don't use it, it's used internally.
    public static var open: AnyView?
}

struct contentView: View {
    var body: some View {
        VStack {
            // create a button that opens a new window
            Button("open a new window") {
                ExternalEvents.open = AnyView(
                    newWindow(id: 0, WindowName: "I am a new window!" )
                )
                guard let url = URL(string: "your-url://newWindow") else { return }
                NSWorkspace.shared.open(url)
            }

        }
    }
}

struct newWindow: View {
    var id: Int
    var WindowName: String
    var body: some View{
        VStack{
            Text(WindowName + String(id))
        }
    }
}
</code>```

I'm not sure if this is the best way to pass variables to a new window, but it does the job quite convincingly.
I'm happy about any solution approaches and ideas.

Body:
I'm trying to use the new WindowGroup to display a more complex view in a new window but somehow I can't figure out how to pass values into the view.

Until yet I was playing around with NSWindow but there I can't use the new toolbar with .toolbar{} and I'm somehow getting weird errors when using the latest swiftUI features.

In my old code I just could pass my values into the new view like usual:

.simultaneousGesture(TapGesture(count: 2).onEnded {

      var window: NSWindow!

      if nil == window {
           let serverView = serverView(content: content) // parse my struct content(name: "XServe-Test", configFile: "/FileUrl", permissions: .rootPermissions, cluster: cluster(x12, CPUMax: .cores(28), ramMax: .gb(1200)))
           window = NSWindow(
           contentRect: NSRect(x: 20, y: 20, width: 580, height: 400),
           styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
            backing: .buffered,
            defer: false)
            window.center()
            window.setFrameAutosaveName("ServerMainView")
            window.isReleasedWhenClosed = false
            window.title = content.name
            window.contentView = NSHostingView(rootView: serverView)
            window.toolbar = NSToolbar()
            window.toolbarStyle = .unifiedCompact
         }

      window.makeKeyAndOrderFront(nil)
 }

Now I'm using in the app file:

import SwiftUI

@main
struct myApp: App {

    var body: some Scene {

        WindowGroup {
            contentView()
        }.windowStyle(HiddenTitleBarWindowStyle())
        .commands {
            SidebarCommands()
            ToolbarCommands()
        }

        // the view that should be displayed in a new window
        WindowGroup("serverView") {
            let inputContent : content = content(name: "XServe-Test", configFile: "/FileUrl", permissions: .rootPermissions, cluster: cluster(x12, CPUMax: .cores(28), ramMax: .gb(1200)))
            serverView(content: inputContent) // this is static now :(
        }.handlesExternalEvents(matching: Set(arrayLiteral: "serverView"))
}

and the following code to open the view:

  .simultaneousGesture(TapGesture(count: 2).onEnded {

  guard let url = URL(string: "com-code-myApp://serverView") else { return }
        NSWorkspace.shared.open(url)
}

How do I pass the input from the tap gesture into the new view using the WindowGroup logic?

Body:
I found two ways to solve this problem. I'm using the first one, because my application is file based. The second solution is based on the great Pulse git repo.

In both cases you need to register a custom URL in the Xcode project settings under:

Tragets -> yourApp -> Info -> URL Types, otherwise it won't work.

first solution:

import SwiftUI

@main
struct myApp: App {

    var body: some Scene {
        // 'default' view
        WindowGroup { contentView() }

        // the view that should open if someone opens your file
        WindowGroup("fileView") { fileView() }
        .handlesExternalEvents(matching: ["file"]) // does the magic

    }
}

struct fileView: View {
    var body: some View {
        VStack{ /* your view content */}
        .onOpenURL(perform: { url in
            // get url and read e.g.: your info file
        })
    }
}

// you can open a file using:
Button("openMyFileinAnExtraWindow"){
   let fileUrl = URL(fileURLWithPath: "~/Documents/myFile.yourExtension")
   NSWorkspace.shared.open(fileUrl)
}

second solution:

Notice: I created this code snippet based on the great Pulse git repo.

import SwiftUI

@main
struct myApp: App {

    var body: some Scene {
        // 'default' view
        WindowGroup { contentView() }

        // the view that should open if someone opens your file
        WindowGroup { DetailsView() }
        .handlesExternalEvents(matching: Set(arrayLiteral: "newWindow")) // this url must be registerd

    }
}

struct DetailsView: View {
    var body: some View {
        ExternalEvents.open
    }
}

public struct ExternalEvents {
    /// - warning: Don't use it, it's used internally.
    public static var open: AnyView?
}

struct contentView: View {
    var body: some View {
        VStack {
            // create a button that opens a new window
            Button("open a new window") {
                ExternalEvents.open = AnyView(
                    newWindow(id: 0, WindowName: "I am a new window!" )
                )
                guard let url = URL(string: "your-url://newWindow") else { return }
                NSWorkspace.shared.open(url)
            }

        }
    }
}

struct newWindow: View {
    var id: Int
    var WindowName: String
    var body: some View{
        VStack{
            Text(WindowName + String(id))
        }
    }
}

I'm not sure if this is the best way to pass variables to a new window, but it does the job quite convincingly.
I'm happy about any solution approaches and ideas.


问:
Detecting application becoming going to the background and coming back to the foreground
I have a macOS app that needs to do some cleanups when the app looses focus (goes to the background), and some reloading of stuff when the it gains focus again (the app is now back in the foreground).

I have tried this code, both on the views and on the main app scene:

```<code>struct ContentView: View {
    @Environment(\.scenePhase) var scenePhase

    var body: some View {
        Text("Hello, world!")
            .padding()
            .onChange(of: scenePhase) { newPhase in
                if newPhase == .active {
                    print("Active")
                } else if newPhase == .inactive {
                    print("Inactive")
                } else if newPhase == .background {
                    print("Background")
                }
            }
    }
}
</code>```

But I only receive an active state. Nothing else.
I have also tried:

```<code>.onReceive(NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)) { (_) in
          print("UIApplication: active")
}
.onReceive(NotificationCenter.default.publisher(for: UIApplication.willResignActiveNotification)) { (_) in
          print("UIApplication: background")
}
</code>```

But I can't get it to work.

How can I detect when the application goes to the background, and then the user brings it back to the front to work on it?

EDIT:

I created an appdelegate and it triggers, but only sometimes

```<code>class AppDelegate: NSObject, NSApplicationDelegate {

    func applicationDidBecomeActive(_ aNotification: Notification) {
        print(">> app coming back, reloading data...")
    }

}
</code>```

答:
this always worked for me:</p>
```<code>@main
struct MyApp: App {

    var body: some Scene {
        WindowGroup {
            ContentView()
        }

        .onChange(of: scenePhase) { phase in
            if phase == .inactive || phase == .background {
                // save
            }
        }
    }
}
</code>```

Body:
I have a macOS app that needs to do some cleanups when the app looses focus (goes to the background), and some reloading of stuff when the it gains focus again (the app is now back in the foreground).

I have tried this code, both on the views and on the main app scene:

struct ContentView: View {
    @Environment(\.scenePhase) var scenePhase

    var body: some View {
        Text("Hello, world!")
            .padding()
            .onChange(of: scenePhase) { newPhase in
                if newPhase == .active {
                    print("Active")
                } else if newPhase == .inactive {
                    print("Inactive")
                } else if newPhase == .background {
                    print("Background")
                }
            }
    }
}

But I only receive an active state. Nothing else.
I have also tried:

.onReceive(NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)) { (_) in
          print("UIApplication: active")
}
.onReceive(NotificationCenter.default.publisher(for: UIApplication.willResignActiveNotification)) { (_) in
          print("UIApplication: background")
}

But I can't get it to work.

How can I detect when the application goes to the background, and then the user brings it back to the front to work on it?

EDIT:

I created an appdelegate and it triggers, but only sometimes

class AppDelegate: NSObject, NSApplicationDelegate {

    func applicationDidBecomeActive(_ aNotification: Notification) {
        print(">> app coming back, reloading data...")
    }

}

Body:
this always worked for me:

@main
struct MyApp: App {

    var body: some Scene {
        WindowGroup {
            ContentView()
        }

        .onChange(of: scenePhase) { phase in
            if phase == .inactive || phase == .background {
                // save
            }
        }
    }
}


问:
Dynamic variable declaration. Is this even the right method?
A little new to JS so be gentle :)

I'm trying to create a program that holds 5000+ boolean values that dynamically change based on other vars.

const chars = "abcdefghijklmnopqrstuvwxyz0";
const charsC = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0"
const maxNum = 48;
const maxTile = 6;
var tile1, tile2, tile3, tile4, tile5, tile6
// test vars
var tile4 = "A27"
var t4a27 = false

// this snippet will be in an interval loop
for (let i = 1; i <= maxTile; ++i) {
    for (let n = 0; n < chars.length; ++n) {
        for (let j = 1; j <= maxNum; ++j) {
            // this obviously doesnt work
            var t[i][`${chars[n]}`][j];
            // ^ ^ ^
            if (tile[i] == `${charsC[n]}${j}`) {
                t[i][h][j] = true;
                console.log(t4a27)
            } else {
                t[i][h][j] = false;
            }
        }
    }
}```

For clarification a better word than "tile" for the vars could be "sprite" rather because its a point on the sprite.

The basic concept is the tile vars are designed to output their current position as a string value e.g. "A27". Then this loop will take that information and scan each tile subset to be true/false. So if the sprite lower right quadrant is inside "A27" the output would be t4a27 = true

In practice I can do this with just a lot of code (over 20,000 lines) but I figured their has to be an easier way that requires far less code.

答:
I think you should use a 2-dim array for this. Or use a regular array of booleans with the appropriate size and do the index-magic yourself.

As you said, you are running on coordinates. A-27 is the same as row(1)+field(27) -- considering A is 1

If your field is 500x100, you create an Array as such: let gamefield = Array(500*100);

Warning: I have not tested this for syntax errors, but you should get the idea.

```<code>let gamefield = Array(500*100);
// optional gamefield.fill(true);

let row = idx => idx * 500;
let posIdx = (r, c) => row(r) + c;

// there is a sprite with a tiles property that returns
// 4 index positions for the sprite's quadrants as [r,c]
let quadrants = sprite.tiles.reportPositions()

// filter the quadrants where the gamefield at r,c is true
// this might also be a good case for some() instead of filter()
let collisions = quadrants.filter(pos => return gamefield[posIdx(...pos)]);

// if there is any of these, you can kill the sprite.
if(collisions.length > 0) sprite.kill();

</code>```

Body:
A little new to JS so be gentle :)

I'm trying to create a program that holds 5000+ boolean values that dynamically change based on other vars.

const chars = "abcdefghijklmnopqrstuvwxyz0";
const charsC = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0"
const maxNum = 48;
const maxTile = 6;
var tile1, tile2, tile3, tile4, tile5, tile6
// test vars
var tile4 = "A27"
var t4a27 = false

// this snippet will be in an interval loop
for (let i = 1; i <= maxTile; ++i) {
    for (let n = 0; n < chars.length; ++n) {
        for (let j = 1; j <= maxNum; ++j) {
            // this obviously doesnt work
            var t[i][`${chars[n]}`][j];
            // ^ ^ ^
            if (tile[i] == `${charsC[n]}${j}`) {
                t[i][h][j] = true;
                console.log(t4a27)
            } else {
                t[i][h][j] = false;
            }
        }
    }
}

For clarification a better word than "tile" for the vars could be "sprite" rather because its a point on the sprite.

The basic concept is the tile vars are designed to output their current position as a string value e.g. "A27". Then this loop will take that information and scan each tile subset to be true/false. So if the sprite lower right quadrant is inside "A27" the output would be t4a27 = true

In practice I can do this with just a lot of code (over 20,000 lines) but I figured their has to be an easier way that requires far less code.

Body:
I think you should use a 2-dim array for this. Or use a regular array of booleans with the appropriate size and do the index-magic yourself.

As you said, you are running on coordinates. A-27 is the same as row(1)+field(27) -- considering A is 1

If your field is 500x100, you create an Array as such: let gamefield = Array(500*100);

Warning: I have not tested this for syntax errors, but you should get the idea.

let gamefield = Array(500*100);
// optional gamefield.fill(true);

let row = idx => idx * 500;
let posIdx = (r, c) => row(r) + c;

// there is a sprite with a tiles property that returns
// 4 index positions for the sprite's quadrants as [r,c]
let quadrants = sprite.tiles.reportPositions()

// filter the quadrants where the gamefield at r,c is true
// this might also be a good case for some() instead of filter()
let collisions = quadrants.filter(pos => return gamefield[posIdx(...pos)]);

// if there is any of these, you can kill the sprite.
if(collisions.length > 0) sprite.kill();


问:
Undefined array key in nested array loop php
I have been trying but i don't know how i can create something like that dynamically without this warnings, $response[$item[0]][$item[1]] += 1; that line is where i struggling to run without php warnings of undefined, thats my code

   $data = [
        'blue-XG',
        'white-PP',
        'blue-XG',
        'black-PP',
        'black-M',
        'white-G',
        'black-G',
        'vermelho-M',
        'black-GG',
        'blue-P',
        'black-GG',
        'blue-XG',
    ];
    sort($data);

    $formatted = array_map(fn($c) => explode('-', $c), $data);

    $response = [];
    foreach ($formatted as $item) {
        $response[$item[0]][$item[1]] += 1;
    }

    print_r($response);
```
<p>and that is my output</p>
```➜ /tmp php product.php
PHP Warning:  Undefined array key "black" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "G" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "GG" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "M" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "PP" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "blue" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "P" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "XG" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "vermelho" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "M" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "white" in /tmp/product.php on line 34
PHP Warning:
PHP Warning:  Undefined array key "black" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "G" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "GG" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "M" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "PP" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "blue" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "P" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "XG" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "vermelho" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "M" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "white" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "G" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "PP" in /tmp/product.php on line 34
Array
(
    [black] => Array
        (
            [G] => 1
            [GG] => 2
            [M] => 1
            [PP] => 1
        )

    [blue] => Array
        (
            [P] => 1
            [XG] => 3
        )

    [red] => Array
        (
            [M] => 1
        )

    [white] => Array
        (
            [G] => 1
            [PP] => 1
        )

```
<p>I want to achieve this output, my output kind of works, but with php warnings, i just want to fix the undefined array keys in the output block</p>
```[
    'black' =>  [
        'PP' => 1,
        'M' => 1,
        'G' => 1,
        'GG' => 2
    ],
    'white' => [
        'PP'=> 1,
        'G' => 1
    ],
    'red' => [
        'M' => 1
    ],
    'blue' => [
        'XG' => 3,
        'P' => 1
    ]
]
```

答:
```<code><?php

$data = [
    'blue-XG',
    'white-PP',
    'blue-XG',
    'black-PP',
    'black-M',
    'white-G',
    'black-G',
    'vermelho-M',
    'black-GG',
    'blue-P',
    'black-GG',
    'blue-XG',
];
sort($data);

$formatted = array_map(fn($c) => explode('-', $c), $data);

$response = [];
foreach ($formatted as $item) {
    // if $response does not have $item[0] key, create it
    if (!isset($response[$item[0]])) {
        $response[$item[0]] = [];
    }

    // if $response does not have $item[0][$item1] value, create it and add 0 value
    if (!isset($response[$item[0]][$item[1]])) {
        $response[$item[0]][$item[1]] = 0;
    }

    ++$response[$item[0]][$item[1]];
}

print_r($response);
</code>```

you can check isset on usage.

The problem is on first iteration of each index of the colours, they do not exist and needs to be created first.

Body:
I have been trying but i don't know how i can create something like that dynamically without this warnings, $response[$item[0]][$item[1]] += 1; that line is where i struggling to run without php warnings of undefined, thats my code

   $data = [
        'blue-XG',
        'white-PP',
        'blue-XG',
        'black-PP',
        'black-M',
        'white-G',
        'black-G',
        'vermelho-M',
        'black-GG',
        'blue-P',
        'black-GG',
        'blue-XG',
    ];
    sort($data);

    $formatted = array_map(fn($c) => explode('-', $c), $data);

    $response = [];
    foreach ($formatted as $item) {
        $response[$item[0]][$item[1]] += 1;
    }

    print_r($response);

and that is my output

➜ /tmp php product.php
PHP Warning:  Undefined array key "black" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "G" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "GG" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "M" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "PP" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "blue" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "P" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "XG" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "vermelho" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "M" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "white" in /tmp/product.php on line 34
PHP Warning:
PHP Warning:  Undefined array key "black" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "G" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "GG" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "M" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "PP" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "blue" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "P" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "XG" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "vermelho" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "M" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "white" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "G" in /tmp/product.php on line 34
PHP Warning:  Undefined array key "PP" in /tmp/product.php on line 34
Array
(
    [black] => Array
        (
            [G] => 1
            [GG] => 2
            [M] => 1
            [PP] => 1
        )

    [blue] => Array
        (
            [P] => 1
            [XG] => 3
        )

    [red] => Array
        (
            [M] => 1
        )

    [white] => Array
        (
            [G] => 1
            [PP] => 1
        )

I want to achieve this output, my output kind of works, but with php warnings, i just want to fix the undefined array keys in the output block

[
    'black' =>  [
        'PP' => 1,
        'M' => 1,
        'G' => 1,
        'GG' => 2
    ],
    'white' => [
        'PP'=> 1,
        'G' => 1
    ],
    'red' => [
        'M' => 1
    ],
    'blue' => [
        'XG' => 3,
        'P' => 1
    ]
]

Body:
<?php

$data = [
    'blue-XG',
    'white-PP',
    'blue-XG',
    'black-PP',
    'black-M',
    'white-G',
    'black-G',
    'vermelho-M',
    'black-GG',
    'blue-P',
    'black-GG',
    'blue-XG',
];
sort($data);

$formatted = array_map(fn($c) => explode('-', $c), $data);

$response = [];
foreach ($formatted as $item) {
    // if $response does not have $item[0] key, create it
    if (!isset($response[$item[0]])) {
        $response[$item[0]] = [];
    }

    // if $response does not have $item[0][$item1] value, create it and add 0 value
    if (!isset($response[$item[0]][$item[1]])) {
        $response[$item[0]][$item[1]] = 0;
    }

    ++$response[$item[0]][$item[1]];
}

print_r($response);

you can check isset on usage.

The problem is on first iteration of each index of the colours, they do not exist and needs to be created first.


问:
Twitter on Android (how to get Date and time of the feed )
Actually i am making an android application which is integrated with the Twitter Feeds.
As i am able to get the corresponding tweets(feeds) of a specific user by the parsing of a JSONArray, which is coming from the twitter server.
But the DATE and TIME of those feeds is not there in that JSONAarray(response).

So do any one know, how to get the DATE and TIME of corresponding twitter feeds.

The code which I am using for getting the feeds is:

```<code>package com.tweet.example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONObject;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
public class Home extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        String readTwitterFeed = readTwitterFeed();
        try {
            JSONArray jsonArray = new JSONArray(readTwitterFeed);
            Log.i(Home.class.getName(),
                    "Number of entries " + jsonArray.length());
            for (int i = 0; i < jsonArray.length(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                Log.i(Home.class.getName(), jsonObject.getString("text"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public String readTwitterFeed() {
        StringBuilder builder = new StringBuilder();
        HttpClient client = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet(
                "http://twitter.com/statuses/user_timeline/<USERNAME>.json");
        try {
            HttpResponse response = client.execute(httpGet);
            StatusLine statusLine = response.getStatusLine();
            int statusCode = statusLine.getStatusCode();
            if (statusCode == 200) {
                HttpEntity entity = response.getEntity();
                InputStream content = entity.getContent();
                BufferedReader reader = new BufferedReader(
                        new InputStreamReader(content));
                String line;
                while ((line = reader.readLine()) != null) {
                    builder.append(line);
                }
            } else {
                Log.e(Home.class.toString(), "Failed to download file");
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return builder.toString();
    }
}
</code>```

NOTE:  Please give some working username @  ("http://twitter.com/statuses/user_timeline/.json");)

Thanks  in advance

答: Hmmm the timestamp is totally there, it's in the created_at field. Take a look at http://twitter.com/statuses/user_timeline/gruber.json.

Body:
Actually i am making an android application which is integrated with the Twitter Feeds.
As i am able to get the corresponding tweets(feeds) of a specific user by the parsing of a JSONArray, which is coming from the twitter server.
But the DATE and TIME of those feeds is not there in that JSONAarray(response).

So do any one know, how to get the DATE and TIME of corresponding twitter feeds.

The code which I am using for getting the feeds is:

package com.tweet.example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONObject;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
public class Home extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        String readTwitterFeed = readTwitterFeed();
        try {
            JSONArray jsonArray = new JSONArray(readTwitterFeed);
            Log.i(Home.class.getName(),
                    "Number of entries " + jsonArray.length());
            for (int i = 0; i < jsonArray.length(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                Log.i(Home.class.getName(), jsonObject.getString("text"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public String readTwitterFeed() {
        StringBuilder builder = new StringBuilder();
        HttpClient client = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet(
                "http://twitter.com/statuses/user_timeline/<USERNAME>.json");
        try {
            HttpResponse response = client.execute(httpGet);
            StatusLine statusLine = response.getStatusLine();
            int statusCode = statusLine.getStatusCode();
            if (statusCode == 200) {
                HttpEntity entity = response.getEntity();
                InputStream content = entity.getContent();
                BufferedReader reader = new BufferedReader(
                        new InputStreamReader(content));
                String line;
                while ((line = reader.readLine()) != null) {
                    builder.append(line);
                }
            } else {
                Log.e(Home.class.toString(), "Failed to download file");
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return builder.toString();
    }
}

NOTE:  Please give some working username @  ("http://twitter.com/statuses/user_timeline/.json");)

Thanks  in advance


问:
@change not working with select tag in Vue3 composition API
I tried @change and watch as well. None of them seem to work.

How to detect when select value is changed?

Here is my code:

```<code> <select v-model="selected" @change="changeLang()" >
    <option v-for="item in langList" :key="item.text" :value="item.lang">
      {{ item.text }}
    </option>
 </select>

function changeLang()
{
   console.log("Called>>>>");
}

watch(() => selected, (first, second) => {
      console.log(
        "Watch props.selected function called with args:",
        first,
        second
      );
});
</code>```

答:
Try like following snippet:

const { ref } = Vue
const app = Vue.createApp({
  setup() {
    const selected = ref(null)
    const langList = ref([{text:'en', lang: 'english'}, {text:'de', lang: 'deutsch'}, {text:'it', lang:'italian'}])

    const changeLang = () => {
      console.log("Called>>>>", selected.value);
    }

    return {
      selected, langList, changeLang
    }
  }
})
app.mount('#demo')```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://unpkg.com/vue@3.2.29/dist/vue.global.prod.js"></script>
<div id="demo">
  <select v-model="selected" @change="changeLang()" >
    <option v-for="item in langList" :key="item.text" :value="item.lang">
      {{ item.text }}
    </option>
 </select>
</div></code>```

Body:
I tried @change and watch as well. None of them seem to work.

How to detect when select value is changed?

Here is my code:

 <select v-model="selected" @change="changeLang()" >
    <option v-for="item in langList" :key="item.text" :value="item.lang">
      {{ item.text }}
    </option>
 </select>

function changeLang()
{
   console.log("Called>>>>");
}

watch(() => selected, (first, second) => {
      console.log(
        "Watch props.selected function called with args:",
        first,
        second
      );
});

Body:
Try like following snippet:

const { ref } = Vue
const app = Vue.createApp({
  setup() {
    const selected = ref(null)
    const langList = ref([{text:'en', lang: 'english'}, {text:'de', lang: 'deutsch'}, {text:'it', lang:'italian'}])

    const changeLang = () => {
      console.log("Called>>>>", selected.value);
    }

    return {
      selected, langList, changeLang
    }
  }
})
app.mount('#demo')

<script src="https://unpkg.com/vue@3.2.29/dist/vue.global.prod.js"></script>
<div id="demo">
  <select v-model="selected" @change="changeLang()" >
    <option v-for="item in langList" :key="item.text" :value="item.lang">
      {{ item.text }}
    </option>
 </select>
</div>


问:
Is there a better way to filter mails based on date?
Well I have run into a problem.

I am using the MS outlook API using C # to generate a few excel based reports from the emails that I receive.

Now initially when I started this, it was OK as the number emails were a little less in the folder. Now after a few days, the number has gone into thousands.

```<code> Application app = null;
            _NameSpace ns = null;
            MailItem item = null;
            MAPIFolder inboxFolder = null;
            MAPIFolder subFolder = null;

            DateTime MyDateTime;
            MyDateTime = new DateTime();
            MyDateTime = DateTime.ParseExact(dateFilter, "yyyy-MM-dd HH:mm tt", null);

            try
            {
                app = new Application();
                ns = app.GetNamespace("MAPI");
                ns.Logon(null, null, false, false);

                inboxFolder = ns.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);
                subFolder = inboxFolder.Folders["Alerts"];

                for (int i = 1; i <= subFolder.Items.Count; i++)
                {
                    item = (Microsoft.Office.Interop.Outlook.MailItem)subFolder.Items[i];

                    string subject = item.Subject;
                    DateTime sent = item.SentOn;

                    if (item.SentOn > MyDateTime && item.SentOn < MyDateTime.AddDays(1))
{//Do some logging
}}
</code>```

Now the issue with the above code is that it starts searching from the last email received. This is causing it to increase the time it takes to reach the "filter".

I need suggestions to improve my code, if any.

Thanks for reading me out.

答:
This is how I filter Outlook appointments.
For mails you need .olFolderInbox instead of .olFolderCalendar.

https://learn.microsoft.com/en-us/dotnet/api/microsoft.office.interop.outlook._items.restrict?view=outlook-pia

```<code>        Microsoft.Office.Interop.Outlook.Application oApp = new Microsoft.Office.Interop.Outlook.Application();
        NameSpace mapiNamespace = oApp.GetNamespace("MAPI");
        MAPIFolder calendarFolder = mapiNamespace.GetDefaultFolder(OlDefaultFolders.olFolderCalendar);

        DateTime filterDate = DateTime.Now;
        string filterDateString = filterDate.Day + "/" + filterDate.Month + "/" + filterDate.Year + " 1:00am";
        string filter = "[CreationTime] > '" + string.Format(filterDateString, "ddddd h:nn AMPM") + "'";
        Items outlookCalendarItems = calendarFolder.Items.Restrict(filter);

        foreach (AppointmentItem item in outlookCalendarItems)
        {
           // Here I write to our database
        }
</code>```

Body:
Well I have run into a problem.

I am using the MS outlook API using C # to generate a few excel based reports from the emails that I receive.

Now initially when I started this, it was OK as the number emails were a little less in the folder. Now after a few days, the number has gone into thousands.

 Application app = null;
            _NameSpace ns = null;
            MailItem item = null;
            MAPIFolder inboxFolder = null;
            MAPIFolder subFolder = null;

            DateTime MyDateTime;
            MyDateTime = new DateTime();
            MyDateTime = DateTime.ParseExact(dateFilter, "yyyy-MM-dd HH:mm tt", null);

            try
            {
                app = new Application();
                ns = app.GetNamespace("MAPI");
                ns.Logon(null, null, false, false);

                inboxFolder = ns.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);
                subFolder = inboxFolder.Folders["Alerts"];

                for (int i = 1; i <= subFolder.Items.Count; i++)
                {
                    item = (Microsoft.Office.Interop.Outlook.MailItem)subFolder.Items[i];

                    string subject = item.Subject;
                    DateTime sent = item.SentOn;

                    if (item.SentOn > MyDateTime && item.SentOn < MyDateTime.AddDays(1))
{//Do some logging
}}

Now the issue with the above code is that it starts searching from the last email received. This is causing it to increase the time it takes to reach the "filter".

I need suggestions to improve my code, if any.

Thanks for reading me out.

Body:
This is how I filter Outlook appointments.
For mails you need .olFolderInbox instead of .olFolderCalendar.

https://learn.microsoft.com/en-us/dotnet/api/microsoft.office.interop.outlook._items.restrict?view=outlook-pia

        Microsoft.Office.Interop.Outlook.Application oApp = new Microsoft.Office.Interop.Outlook.Application();
        NameSpace mapiNamespace = oApp.GetNamespace("MAPI");
        MAPIFolder calendarFolder = mapiNamespace.GetDefaultFolder(OlDefaultFolders.olFolderCalendar);

        DateTime filterDate = DateTime.Now;
        string filterDateString = filterDate.Day + "/" + filterDate.Month + "/" + filterDate.Year + " 1:00am";
        string filter = "[CreationTime] > '" + string.Format(filterDateString, "ddddd h:nn AMPM") + "'";
        Items outlookCalendarItems = calendarFolder.Items.Restrict(filter);

        foreach (AppointmentItem item in outlookCalendarItems)
        {
           // Here I write to our database
        }


问:
Is it a good thing to use label / text to verify that element is found on the current page?
I'm new with robot framework so my qst is :
in order to verify if a field exists on a page,is it good to use the field label  for that :

```<code>${element_to_test}    //label[contains(text(),'test1, test2, test3')]
</code>```

NB / I got this xpath by using chropath tool after selecting the target field
thanks guys

答:
Not the best selector since the test will fail when the text changes.
Best is to use a testid for interacting with elements.

See:
https://docs.cypress.io/guides/references/best-practices#Selecting-Elements

(Written for Cypress, but locating strategies are basically the same between all frameworks)

Body:
I'm new with robot framework so my qst is :
in order to verify if a field exists on a page,is it good to use the field label  for that :

${element_to_test}    //label[contains(text(),'test1, test2, test3')]

NB / I got this xpath by using chropath tool after selecting the target field
thanks guys


问:
Retrofit GET Query with api key:
Hello I am trying to use Retrofit to access a URL : https://my.api.mockaroo.com/products?key=57b501f0

here is my interface:

```<code>interface ProductInterface {
    @GET("products?")
    suspend fun getTodos(@Query("key") key: String): Response<List<product>>
}
</code>```

here is my Retrofit Object

```<code>object RetrofitInstance {
    val api: ProductInterface by lazy<ProductInterface> {
        Log.e("Request", "Sent")
        Retrofit.Builder()
            .baseUrl("https://my.api.mockaroo.com/")
            .addConverterFactory(GsonConverterFactory.create())
            .build()
            .create(ProductInterface::class.java)
    }
}
</code>```

and here it is how i am accessing it:

```<code>RetrofitInstance.api.getTodos("57b501f0")
</code>```

But When i logged its working, It says following URL: https://my.api.mockaroo.com/products?&key=57b501f0

was accessed instead of : https://my.api.mockaroo.com/products?key=57b501f0

How can i resolve this?

答:
In retrofit when you pass the queries,it will append to the URL with questionmark(?).if there is more than one queries is append then it uses the & sign for that so you have already mentioned the ? in the @GET("products?") so its considering the query added in the request as extra so its using the & for that.please remove the ? from the  @GET("products?") .it will work fine

```<code>interface ProductInterface {
    @GET("products")
    suspend fun getTodos(@Query("key") key: String): Response<List<product>>
}
</code>```

Refer this link for more info about Api Request

Title: Retrofit GET Query with api key:

Body:
Hello I am trying to use Retrofit to access a URL : https://my.api.mockaroo.com/products?key=57b501f0

here is my interface:

interface ProductInterface {
    @GET("products?")
    suspend fun getTodos(@Query("key") key: String): Response<List<product>>
}

here is my Retrofit Object

object RetrofitInstance {
    val api: ProductInterface by lazy<ProductInterface> {
        Log.e("Request", "Sent")
        Retrofit.Builder()
            .baseUrl("https://my.api.mockaroo.com/")
            .addConverterFactory(GsonConverterFactory.create())
            .build()
            .create(ProductInterface::class.java)
    }
}

and here it is how i am accessing it:

RetrofitInstance.api.getTodos("57b501f0")

But When i logged its working, It says following URL: https://my.api.mockaroo.com/products?&key=57b501f0

was accessed instead of : https://my.api.mockaroo.com/products?key=57b501f0

How can i resolve this?

Body:
In retrofit when you pass the queries,it will append to the URL with questionmark(?).if there is more than one queries is append then it uses the & sign for that so you have already mentioned the ? in the @GET("products?") so its considering the query added in the request as extra so its using the & for that.please remove the ? from the  @GET("products?") .it will work fine

interface ProductInterface {
    @GET("products")
    suspend fun getTodos(@Query("key") key: String): Response<List<product>>
}

Refer this link for more info about Api Request


问:
How to enable UDST in java?
I have created a new GCP instance and used defaulted Debian system.
Then, I use apt to install the default-java package, but they're no USDT in libjvm.so. I don't know why?

information:

$ uname -a
Linux bpf-test1 4.19.0-18-cloud-amd64 #1 SMP Debian 4.19.208-1 (2021-09-29) x86_64 GNU/Linux

$ whereis java
java: /usr/share/java /usr/lib/jvm/java-11-openjdk-amd64/bin/java /usr/share/man/man1/java.1.gz

$ java -version
openjdk version "11.0.13" 2021-10-19
OpenJDK Runtime Environment (build 11.0.13+8-post-Debian-1deb10u1)
OpenJDK 64-Bit Server VM (build 11.0.13+8-post-Debian-1deb10u1, mixed mode, sharing)

$ readelf -n $JAVA_HOME/lib/server/libjvm.so
Displaying notes found in: .note.gnu.build-id
  Owner                 Data size   Description
  GNU                  0x00000014   NT_GNU_BUILD_ID (unique build ID bitstring)
    Build ID: 5a4af8c3edd4e64e7fd351d2e18dce9947db4d22

$ ps -ef|grep java
xxx   23001 22956  1 13:08 pts/0    00:00:30 java -jar xxx.jar
xxx   23157 23042  0 13:44 pts/1    00:00:00 grep java

$ sudo javathreads-bpfcc  23001
Error attaching USDT probes: the specified pid might not contain the
given language's runtime, or the runtime was not built with the required
USDT probes. Look for a configure flag similar to --with-dtrace or
--enable-dtrace. To check which probes are present in the process, use the
tplist tool.

$ cat /boot/config-$(uname -r) | grep BPF
CONFIG_CGROUP_BPF=y
CONFIG_BPF=y
CONFIG_BPF_SYSCALL=y
# CONFIG_BPF_JIT_ALWAYS_ON is not set
CONFIG_IPV6_SEG6_BPF=y
CONFIG_NETFILTER_XT_MATCH_BPF=m
# CONFIG_BPFILTER is not set
CONFIG_NET_CLS_BPF=m
CONFIG_NET_ACT_BPF=m
CONFIG_BPF_JIT=y
CONFIG_BPF_STREAM_PARSER=y
CONFIG_LWTUNNEL_BPF=y
CONFIG_HAVE_EBPF_JIT=y
CONFIG_BPF_EVENTS=y
# CONFIG_BPF_KPROBE_OVERRIDE is not set
# CONFIG_TEST_BPF is not set

$ cat /boot/config-$(uname -r) | grep TRACEPOINT
CONFIG_TRACEPOINTS=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
# CONFIG_TRACEPOINT_BENCHMARK is not set
```

答:
Kernel has nothing to do USDT probes, since these have to be in the libjvm.so. Unfortunately you didn't specify your debian version, and as far as I know there is no default-java package in the debian (although there is default-[jdk|jre] package). From your java version I could guess that you using this package. Anyway, in order to have USDT probes openjdk has to be complied with --enable-dtrace flag, which isn't used in that package. When openjdk is compiled with this flag you'll have this:

```<code>readelf -n /path/to/openjdk/lib/server/libjvm.so

  stapsdt              0x0000002f       NT_STAPSDT (SystemTap probe descriptors)
    Provider: hotspot
    Name: thread__yield
    Location: 0x000000000098745b, Base: 0x000000000107e7f4, Semaphore: 0x0000000000000000
    Arguments:
  stapsdt              0x0000003d       NT_STAPSDT (SystemTap probe descriptors)
    Provider: hotspot
    Name: thread__sleep__begin
    Location: 0x000000000098ff64, Base: 0x000000000107e7f4, Semaphore: 0x0000000000000000
    Arguments: -8@%r12
  stapsdt              0x00000039       NT_STAPSDT (SystemTap probe descriptors)
    Provider: hotspot
    Name: thread__sleep__end
    Location: 0x000000000098ffa3, Base: 0x000000000107e7f4, Semaphore: 0x0000000000000000
    Arguments: -4@$0
  stapsdt              0x00000039       NT_STAPSDT (SystemTap probe descriptors)
    Provider: hotspot
    Name: thread__sleep__end
    Location: 0x0000000000990100, Base: 0x000000000107e7f4, Semaphore: 0x0000000000000000
    Arguments: -4@$1
</code>```

So your options is either, build openjdk yourself and ensure to use --enable-dtrace flag (this would require systemtap as dependency) or use package that has been provided by someone else. As for prebuild package, I can recommend this prebuild package. Unfortunately, there is no *.deb package there (there is only .tar.gz), but I know for sure that it has been built with --enable-dtrace. I'm recommending this because I know that certain distros using these packages (for example Gentoo).

Title: How to enable UDST in java?

Body:
Kernel has nothing to do USDT probes, since these have to be in the libjvm.so. Unfortunately you didn't specify your debian version, and as far as I know there is no default-java package in the debian (although there is default-[jdk|jre] package). From your java version I could guess that you using this package. Anyway, in order to have USDT probes openjdk has to be complied with --enable-dtrace flag, which isn't used in that package. When openjdk is compiled with this flag you'll have this:

readelf -n /path/to/openjdk/lib/server/libjvm.so

  stapsdt              0x0000002f       NT_STAPSDT (SystemTap probe descriptors)
    Provider: hotspot
    Name: thread__yield
    Location: 0x000000000098745b, Base: 0x000000000107e7f4, Semaphore: 0x0000000000000000
    Arguments:
  stapsdt              0x0000003d       NT_STAPSDT (SystemTap probe descriptors)
    Provider: hotspot
    Name: thread__sleep__begin
    Location: 0x000000000098ff64, Base: 0x000000000107e7f4, Semaphore: 0x0000000000000000
    Arguments: -8@%r12
  stapsdt              0x00000039       NT_STAPSDT (SystemTap probe descriptors)
    Provider: hotspot
    Name: thread__sleep__end
    Location: 0x000000000098ffa3, Base: 0x000000000107e7f4, Semaphore: 0x0000000000000000
    Arguments: -4@$0
  stapsdt              0x00000039       NT_STAPSDT (SystemTap probe descriptors)
    Provider: hotspot
    Name: thread__sleep__end
    Location: 0x0000000000990100, Base: 0x000000000107e7f4, Semaphore: 0x0000000000000000
    Arguments: -4@$1

So your options is either, build openjdk yourself and ensure to use --enable-dtrace flag (this would require systemtap as dependency) or use package that has been provided by someone else. As for prebuild package, I can recommend this prebuild package. Unfortunately, there is no *.deb package there (there is only .tar.gz), but I know for sure that it has been built with --enable-dtrace. I'm recommending this because I know that certain distros using these packages (for example Gentoo).


问:
Windows 10 detect keyboard layout change
I'm trying to implement a service that would monitor language/layout changes. I switch between English and Russian languages. So far I've found this question and tried to implement and install both sinks suggested there.
However, there are problems. ITfActiveLanguageProfileNotifySink::OnActivated is not triggered at all; ITfLanguageProfileNotifySink::OnLanguageChange is not triggered, too; ITfLanguageProfileNotifySink::OnLanguageChanged is triggered only when the main window of my program is in foreground, but it doesn't contain any information on the language. Is there any way to monitor input language change event globally?

答:
I found another way to detect such changes: to use SetWindowsHookEx with WH_SHELL. One of the available event is HSHELL_LANGUAGE which is exactly what I need and the test project seems to work just fine.
There's an article by Alexander Shestakov that describes a program very similar to what I'm trying to achieve and it also has a link to github project that I use as an example.


问:
Moment.js with ReactJS (ES6)
I am new to Moment.js and using ReactJS (ES6) for my project. How can I use moment.js to format a date?

I want to format post.date in the below mentioned loop.

```<code>render() {
    return (
        <div>
            {
            this.props.data.map((post,key) =>
                <div key={key} className="post-detail">
                    <h1>{post.title}</h1>
                    <p>{post.date}</p>
                    <p dangerouslySetInnerHTML={{__html: post.content}}></p>
                    <hr />
                </div>
            )}
        </div>
    );
}
</code>```

答:
HERE YOU GO! (MAGIC SOLUTION)
In order to have a placeholder you must set your state to null first in the SELECTED property so that placeholder would be displayed and after that state would be mount with date user will select from the input tag.</p>
```<code>import React,{useState} from 'react'
function App(){
  const [startDate, setStartDate] = useState();

  return(
    <>
    <DatePicker
      placeholderText="Click to enter the start date"
      **selected={startDate===" " ? null : startDate}**
      onChange={(date) => new Date(setStartDate(date))}
      selectsStart
      startDate={startDate}
      endDate={endDate}

   />
)}
</code>```

Title: Moment.js with ReactJS (ES6)

Body:
I am new to Moment.js and using ReactJS (ES6) for my project. How can I use moment.js to format a date?

I want to format post.date in the below mentioned loop.

render() {
    return (

            {
            this.props.data.map((post,key) =>

{post.title}

{post.date}

            )}

    );
}

Body:
HERE YOU GO! (MAGIC SOLUTION)
In order to have a placeholder you must set your state to null first in the SELECTED property so that placeholder would be displayed and after that state would be mount with date user will select from the input tag.

import React,{useState} from 'react'
function App(){
  const [startDate, setStartDate] = useState();

  return(
    <>
    <DatePicker
      placeholderText="Click to enter the start date"
      **selected={startDate===" " ? null : startDate}**
      onChange={(date) => new Date(setStartDate(date))}
      selectsStart
      startDate={startDate}
      endDate={endDate}

   />
)}


问:
MariaDB: SQL to remove duplicates between different timestamps
I have the following table and want to remove duplicates between the oldest and newest timestamp.

timestamp
type
state

2019-10-01 04:51:42
mod
off

2019-10-01 04:54:42
mod
off

2019-10-01 04:56:42
mod
off

2019-10-01 05:01:42
mod
on

2019-10-01 05:21:42
mod
on

2019-10-01 05:30:42
mod
on

2019-10-01 05:43:42
mod
off

2019-10-01 05:51:42
mod
off

2019-10-01 06:02:42
mod
off

2019-10-01 06:05:42
mod
off

2019-10-01 06:10:42
mod
on

2019-10-01 06:15:42
mod
on

2019-10-01 06:25:42
mod
on

This is the result what I want with a generic SQL statement. I need the first timestamp if status is changed.

timestamp
type
state

2019-10-01 04:51:42
mod
off

2019-10-01 05:01:42
mod
on

2019-10-01 05:43:42
mod
off

2019-10-01 06:10:42
mod
on

Thanks for help :-)

答:
See this DBFIDDLE</p>
```<code>SELECT `timestamp`,type,state
FROM (
  SELECT
    `timestamp`,
    type,
    state,
    LEAD(state) OVER (ORDER BY `timestamp`) as Next,
    LAG(state) OVER (ORDER BY `timestamp`) as Previous
  FROM t1
  ) x
WHERE state=Next AND (state<>Previous OR Previous is null);
</code>```

Body:
See this DBFIDDLE

SELECT `timestamp`,type,state
FROM (
  SELECT
    `timestamp`,
    type,
    state,
    LEAD(state) OVER (ORDER BY `timestamp`) as Next,
    LAG(state) OVER (ORDER BY `timestamp`) as Previous
  FROM t1
  ) x
WHERE state=Next AND (state<>Previous OR Previous is null);


问:
How to set default Background Color for the custom Elementor widget
I want to set a default background color to custom widget when someone drag the widget to page in Elementor Page Builder.

答:
If you have Elementor Pro you can add "Custom CSS" for widgets: https://elementor.com/help/custom-css-pro/.

You can then set these subset of widgets to display the correct background colour or gradient.

Example:

#widget {
  background: linear-gradient(to bottom right, black, grey);
  width: 750px;
  height: 250px;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div id="widget"></div></code>```

Body:
If you have Elementor Pro you can add "Custom CSS" for widgets: https://elementor.com/help/custom-css-pro/.

You can then set these subset of widgets to display the correct background colour or gradient.

Example:

#widget {
  background: linear-gradient(to bottom right, black, grey);
  width: 750px;
  height: 250px;
}

<div id="widget"></div>