问:
Writing an Integer in file with BufferedWriter
I have a method to write a file but somehow it is having problems writing an int:

```<code>public static void writeFile(int[] result) {
    try {
        FileWriter writer = new FileWriter("MyFileExample.txt", true);
        BufferedWriter bufferedWriter = new BufferedWriter(writer);

        int counter = 0;
        for (int j = 0; j < result.length; j++) {
            if (result[j] != -1) {
                counter++;
            }
        }
        System.out.println(counter);

        bufferedWriter.write(counter);

        bufferedWriter.newLine();

        for(int i = 0; i<result.length; i++) {
            if (result[i] != -1) {
                bufferedWriter.write(i + " ");
            }
        }

        bufferedWriter.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
</code>```

The line bufferedWriter.write(counter); is not writing anything. Just a blank. The rest is getting written perfectly fine. I tried writing "test" instead of counter and that is perfectly fine as well.

Any idea on how to fix this issue?

答:
What happened, when you wrote the int without converting it into a String is, it simply wrote the int as the type it is (an int). So invoking the method e.g. as follows:

writeFile(new int[] {1, 2, 3})
```

<p>writes the following bytes to the file:</p>

```03 00 01 02
```

which, if you refer to an ASCII table, are all non-printable characters.

Based on the filetype you want to write, I assume, you want the Integers to be written as Strings. So you just did the right thing to convert it before writing it.

Body:
I have a method to write a file but somehow it is having problems writing an int:

public static void writeFile(int[] result) {
    try {
        FileWriter writer = new FileWriter("MyFileExample.txt", true);
        BufferedWriter bufferedWriter = new BufferedWriter(writer);

        int counter = 0;
        for (int j = 0; j < result.length; j++) {
            if (result[j] != -1) {
                counter++;
            }
        }
        System.out.println(counter);

        bufferedWriter.write(counter);

        bufferedWriter.newLine();

        for(int i = 0; i<result.length; i++) {
            if (result[i] != -1) {
                bufferedWriter.write(i + " ");
            }
        }

        bufferedWriter.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

The line bufferedWriter.write(counter); is not writing anything. Just a blank. The rest is getting written perfectly fine. I tried writing "test" instead of counter and that is perfectly fine as well.

Any idea on how to fix this issue?

Body:
What happened, when you wrote the int without converting it into a String is, it simply wrote the int as the type it is (an int). So invoking the method e.g. as follows:

writeFile(new int[] {1, 2, 3})

writes the following bytes to the file:

03 00 01 02

which, if you refer to an ASCII table, are all non-printable characters.

Based on the filetype you want to write, I assume, you want the Integers to be written as Strings. So you just did the right thing to convert it before writing it.


来源: stackexchange

问:
SignOutAsync deletes cookie but is regenerated when returning to client application?
this is how the logout is done within the api:

```<code>    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task Logout(LogoutRequest logoutContext)
    {
        if (User?.Identity.IsAuthenticated == true)
        {
            var prop = new AuthenticationProperties
            {
                RedirectUri = logoutContext.PostLogoutRedirectUri
            };

            await HttpContext.SignOutAsync(IdentityConstants.ApplicationScheme, prop);
            await _events.RaiseAsync(new UserLogoutSuccessEvent(User.GetSubjectId(), User.GetDisplayName()));
        }
    }
</code>```

in the client app I have the following configuration:

```<code>        services.AddAuthentication(options =>
        {
            options.DefaultScheme = IdentityConstants.ApplicationScheme;
            options.DefaultChallengeScheme = "oidc";
        })
        .AddCookie(IdentityConstants.ApplicationScheme, options => { options.AccessDeniedPath = "/Home/AccessDenied";  })
        .AddOpenIdConnect("oidc", options =>
        {
            options.Authority = model.Authority;
            options.ClientId = model.ClientId;
            options.SignInScheme = IdentityConstants.ApplicationScheme;
            options.ResponseType = "id_token token";
            options.Scope.Add("openid profile");
        });
        services.AddAuthorization(options =>
        {
            options.AddPolicy("User", p => p.RequireAuthenticatedUser().RequireRole("User"));
        });
</code>```

when I log out the cookie is deleted, once I navigate back to the client I am not prompted to log back in and the cookie has returned. is there something I am doing wrong?

答:
You aren't deleting the single sign on cookie generated in your Identity Provider. Your client is redirecting to your Identity Provider and redirecting again to your client with a new authentication since your Identity Provider still maintains the Cookie. Capture the requests in Fiddler to see the automatic redirections.

You should signout from oidc too in order to delete this Cookie:

```<code>await HttpContext.SignOutAsync("oidc");
</code>```

If your want to signout automatically (without the Logout view from your Identity Provider) you can set false ShowLogoutPrompt and set true AutomaticRedirectAfterSignOut in the AccountOptions.cs file.

ContentLicense: CC BY-SA 4.0

Body:
this is how the logout is done within the api:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task Logout(LogoutRequest logoutContext)
    {
        if (User?.Identity.IsAuthenticated == true)
        {
            var prop = new AuthenticationProperties
            {
                RedirectUri = logoutContext.PostLogoutRedirectUri
            };

            await HttpContext.SignOutAsync(IdentityConstants.ApplicationScheme, prop);
            await _events.RaiseAsync(new UserLogoutSuccessEvent(User.GetSubjectId(), User.GetDisplayName()));
        }
    }

in the client app I have the following configuration:

        services.AddAuthentication(options =>
        {
            options.DefaultScheme = IdentityConstants.ApplicationScheme;
            options.DefaultChallengeScheme = "oidc";
        })
        .AddCookie(IdentityConstants.ApplicationScheme, options => { options.AccessDeniedPath = "/Home/AccessDenied";  })
        .AddOpenIdConnect("oidc", options =>
        {
            options.Authority = model.Authority;
            options.ClientId = model.ClientId;
            options.SignInScheme = IdentityConstants.ApplicationScheme;
            options.ResponseType = "id_token token";
            options.Scope.Add("openid profile");
        });
        services.AddAuthorization(options =>
        {
            options.AddPolicy("User", p => p.RequireAuthenticatedUser().RequireRole("User"));
        });

when I log out the cookie is deleted, once I navigate back to the client I am not prompted to log back in and the cookie has returned. is there something I am doing wrong?

Body:
You aren't deleting the single sign on cookie generated in your Identity Provider. Your client is redirecting to your Identity Provider and redirecting again to your client with a new authentication since your Identity Provider still maintains the Cookie. Capture the requests in Fiddler to see the automatic redirections.

You should signout from oidc too in order to delete this Cookie:

await HttpContext.SignOutAsync("oidc");

If your want to signout automatically (without the Logout view from your Identity Provider) you can set false ShowLogoutPrompt and set true AutomaticRedirectAfterSignOut in the AccountOptions.cs file.


问:
@Recover (fallback method) is not getting invoked when used with @CircuitBreaker, once all the retry gets exhaused
Though with other return type Spring retry fallback mechanism seems to be working fine, but when it comes to calling an API with return type void. Recover method is not getting called at all, I have tried with all possible type of method parameters and changing the return type of the fallback method.... Is thr any way to do it? I don't understand why the @CircuitBReaker annotation doesn't have a parameter to take the fallback method name passed as a value to it?</p>

```<code>    @CircuitBreaker(maxAttempts = 3, openTimeout = 8000, resetTimeout = 15000)
    public Void callingXYZ(final Abc abc, final Cdf cdf) {
        return retryTemplate.execute(context -> {
            log.info("Retry count={} when calling ******", context.getRetryCount());
            AbcServiceImpl.this.update*****Settings(OrgId.fromString(abc.getUUID(), cdf.getData());
            return null;
        });
    }

   //Recover method that should get invoked
    @Recover
    public Void fallbackUpdate*****(Throwable e, Abc abc) throws Throwable{
        log.info("Inside fallback");
        if (e instanceof ClientException) {
            log.warn("Fallback method is called when trying to call ******** from ****** because of {}", e.getCause());

   //Rollback in the db based on the method attributes
            throw SpecificException.forTask(HttpStatus.SERVICE_UNAVAILABLE.value(),
                    Enum.NAME.getErrorCode(),
                    Enum.NAME.getMEssage(), true);
        }
        throw e;
    }

</code>```

答:
Try using @Retryable it works for me

```<code> <dependency>
        <groupId>org.springframework.retry</groupId>
        <artifactId>spring-retry</artifactId>
        <version>1.1.5.RELEASE</version>
    </dependency>

@Retryable(value = { NullPointerException.class},maxAttempts = 2)
public void retry() throws NullPointerException{
    throw new NullPointerException("something went wrong");
}

@Recover
public void recover(NullPointerException ex)
{
    System.out.println("iniside recover");
}
</code>```

For more details check this link https://www.baeldung.com/spring-retry

Body:
Though with other return type Spring retry fallback mechanism seems to be working fine, but when it comes to calling an API with return type void. Recover method is not getting called at all, I have tried with all possible type of method parameters and changing the return type of the fallback method.... Is thr any way to do it? I don't understand why the @CircuitBReaker annotation doesn't have a parameter to take the fallback method name passed as a value to it?

    @CircuitBreaker(maxAttempts = 3, openTimeout = 8000, resetTimeout = 15000)
    public Void callingXYZ(final Abc abc, final Cdf cdf) {
        return retryTemplate.execute(context -> {
            log.info("Retry count={} when calling ******", context.getRetryCount());
            AbcServiceImpl.this.update*****Settings(OrgId.fromString(abc.getUUID(), cdf.getData());
            return null;
        });
    }

   //Recover method that should get invoked
    @Recover
    public Void fallbackUpdate*****(Throwable e, Abc abc) throws Throwable{
        log.info("Inside fallback");
        if (e instanceof ClientException) {
            log.warn("Fallback method is called when trying to call ******** from ****** because of {}", e.getCause());

   //Rollback in the db based on the method attributes
            throw SpecificException.forTask(HttpStatus.SERVICE_UNAVAILABLE.value(),
                    Enum.NAME.getErrorCode(),
                    Enum.NAME.getMEssage(), true);
        }
        throw e;
    }

Body:
Try using @Retryable it works for me

 <dependency>
        <groupId>org.springframework.retry</groupId>
        <artifactId>spring-retry</artifactId>
        <version>1.1.5.RELEASE</version>
    </dependency>

@Retryable(value = { NullPointerException.class},maxAttempts = 2)
public void retry() throws NullPointerException{
    throw new NullPointerException("something went wrong");
}

@Recover
public void recover(NullPointerException ex)
{
    System.out.println("iniside recover");
}

For more details check this link https://www.baeldung.com/spring-retry


问:
React update List item state as performant as possible
I am currently creating an React Application with an Editable Details list. My Issue is that I am not managing to update the list in a fast way. Specially Internet Explorer is struggling allot.

It would be to much to use my Application as example so I created a simplified concept in codesandbox:
https://codesandbox.io/s/bold-sanderson-of08y

For this Example I am just Rendering a lot of <input/> and let the parent container handle the state.

```<code>function App() {
   console.log('Render App')

   const [items, setItems] = useState(createItems())

   const handleChange = (value, index) => {
       const itemsCopy = [...items]
       itemsCopy[index] = value
       setItems(itemsCopy)
   }

   const handleSave = () => {
       //Send data to back-end etc...
       //webAPI.saveData(items)
   }

   return (
       <div>
           <button onClick={handleSave}>Save</button>
           <hr />
           {items.map((item, index) => {
               return (
                   <input
                       key={index}
                       value={item}
                       onChange={e => handleChange(e.target.value, index)}
                    />
             )
           })}
       </div>
   )
}
</code>```

This demo is a bit extreme because each key press will trigger an state update. But its fine for this example.

What I want to know is how to handle this situation without re-rendering the "App" component each time. I was thinking of moving the state to the Input component itself, but if I did that I would not be able to assess all data from the handleSave function. Or at least I don't know how this can be accomplished.

答:
Keep in mind that whenever a component renders, every ancestor of that component also rerenders. For this reason keeping state (that you expect to change often) high up in the component tree is typically discouraged. You should try to hold any state as low down in your component tree as possible.

Some ways around this are to bring in a state management library like react-redux which will allow you to have "global" state that doesn't cause the entire tree to rerender, or alternatively you can look into using React.memo on components that don't rely on that list state which will cause them to not rerender when the list changes.

In my own biased opinion, I think React devs tend to jump to using Redux far too quickly. I think applications that rely on redux are very hard to trace through and actually understand what is going on. Instead, I think something like this may work well:

```<code>const App = () => {
  const [items, setItems] = useState(createItems());
  const handleChange = useCallback((value, index) => {
    const itemsCopy = [...items]
    itemsCopy[index] = value
    setItems(itemsCopy)
  }, [setItems]);

  return (
    <div>
      {items.map((item, index) => {
        return (
          <MyInput
            key={index}
            value={item}
            index={index}
            onChange={handleChange}
          />
        )
     })}
    </div>
  )
}

const MyInput = React.memo((props) => {
  return (
    <input
      value={props.value}
      onChange={e => props.onChange(e.target.value, props.index)}
    />
  )
})
</code>```

Having the React.memo on MyInput will prevent each instance of the component from rerendering when one of the other items in the list updates, which is only really possible because of the const handleChange = useCallback(...). By wrapping your handler in useCallback you are guarenteeing that the function is the literally the same function across renders, which allows the memoized components to not need to rerender since the handler is always the same function.

Body:
I am currently creating an React Application with an Editable Details list. My Issue is that I am not managing to update the list in a fast way. Specially Internet Explorer is struggling allot.

It would be to much to use my Application as example so I created a simplified concept in codesandbox:
https://codesandbox.io/s/bold-sanderson-of08y

For this Example I am just Rendering a lot of <input/> and let the parent container handle the state.

function App() {
   console.log('Render App')

   const [items, setItems] = useState(createItems())

   const handleChange = (value, index) => {
       const itemsCopy = [...items]
       itemsCopy[index] = value
       setItems(itemsCopy)
   }

   const handleSave = () => {
       //Send data to back-end etc...
       //webAPI.saveData(items)
   }

   return (

           <button onClick={handleSave}>Save</button>

           {items.map((item, index) => {
               return (
                   <input
                       key={index}
                       value={item}
                       onChange={e => handleChange(e.target.value, index)}
                    />
             )
           })}

   )
}

This demo is a bit extreme because each key press will trigger an state update. But its fine for this example.

What I want to know is how to handle this situation without re-rendering the "App" component each time. I was thinking of moving the state to the Input component itself, but if I did that I would not be able to assess all data from the handleSave function. Or at least I don't know how this can be accomplished.

Body:
Keep in mind that whenever a component renders, every ancestor of that component also rerenders. For this reason keeping state (that you expect to change often) high up in the component tree is typically discouraged. You should try to hold any state as low down in your component tree as possible.

Some ways around this are to bring in a state management library like react-redux which will allow you to have "global" state that doesn't cause the entire tree to rerender, or alternatively you can look into using React.memo on components that don't rely on that list state which will cause them to not rerender when the list changes.

In my own biased opinion, I think React devs tend to jump to using Redux far too quickly. I think applications that rely on redux are very hard to trace through and actually understand what is going on. Instead, I think something like this may work well:

const App = () => {
  const [items, setItems] = useState(createItems());
  const handleChange = useCallback((value, index) => {
    const itemsCopy = [...items]
    itemsCopy[index] = value
    setItems(itemsCopy)
  }, [setItems]);

  return (
    <div>
      {items.map((item, index) => {
        return (
          <MyInput
            key={index}
            value={item}
            index={index}
            onChange={handleChange}
          />
        )
     })}
    </div>
  )
}

const MyInput = React.memo((props) => {
  return (
    <input
      value={props.value}
      onChange={e => props.onChange(e.target.value, props.index)}
    />
  )
})

Having the React.memo on MyInput will prevent each instance of the component from rerendering when one of the other items in the list updates, which is only really possible because of the const handleChange = useCallback(...). By wrapping your handler in useCallback you are guarenteeing that the function is the literally the same function across renders, which allows the memoized components to not need to rerender since the handler is always the same function.


问:
Websocket on Docker with nginx
I am trying to build a service with two parts: a backend and a frontend. Both are on a different docker container and are communicating through the docker-compose configuration and a nginx container.

For https access, everything's good, but when I am trying to work with websocket, I have an upgrade error, even if the Nginx configuration got this information

Error message : websocket: the client is not using the websocket protocol:  'upgrade' token not found in 'Connection' header

I am using a fasthttp and fasthttp/websocket for my Golang backend. The code is working on localhost (no nginx configuration), but the combinaison of Docker + nginx seems to break something.
The front-end works with react and is a simple let socket = new WebSocket(wss.mydomain.com/ws/uploadPicture/);

EDIT :

when using ctx.Request.Header.ConnectionUpgrade() just before upgrader.Upgrade, the result is true, but ctx.Response.Header.ConnectionUpgrade() is false

Thank you !

Golang Backend

var upgrader = websocket.FastHTTPUpgrader{
    ReadBufferSize:  1024,
    WriteBufferSize: 1024,
    CheckOrigin: func(ctx *fasthttp.RequestCtx) bool {
        return true
    },
}
func    InitRouter() func(*fasthttp.RequestCtx) {
    router := fasthttprouter.New()

    router.GET("/ws/uploadPicture/", doWS)

    return router.Handler
}
func    doWS(ctx *fasthttp.RequestCtx) {
    err := upgrader.Upgrade(ctx, func(conn *websocket.Conn) {
        //SHOULD DO STUFF
    })
    if (err != nil) {
        logs.Error(err.Error()) //HIT THIS ERROR
        return
    }
}

...
fasthttp.ListenAndServe(`:8000`, InitRouter())
```

<p><em>Nginx.conf</em></p>

```#############################################################################
## NGINX CONFIGURATION FOR THE WEBAPP
#############################################################################
upstream webapp {
    server webapp:3000;
    keepalive 4;
}
server {
    listen [::]:443 ssl;
    listen 443 ssl;

    server_name mydomain.com;

    ssl_certificate /etc/letsencrypt/live/mydomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/mydomain.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location / {
        proxy_pass http://webapp;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_redirect off;
    }
}

#############################################################################
## NGINX CONFIGURATION FOR THE PROXY
#############################################################################
upstream proxy {
    server proxy:8000;
    keepalive 4;
}
server {
    listen [::]:443 ssl;
    listen 443 ssl;

    server_name api.mydomain.com;

    ssl_certificate /etc/letsencrypt/live/mydomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/mydomain.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location / {
        add_header 'Access-Control-Allow-Origin' "$http_origin";
        add_header 'Access-Control-Allow-Credentials' true;
        proxy_pass http://proxy;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_redirect off;
    }
}

#############################################################################
## NGINX CONFIGURATION FOR THE PROXY
#############################################################################
upstream proxyws {
    server proxy:8000;
    keepalive 4;
}
server {
    listen [::]:443 ssl;
    listen 443 ssl;

    server_name wss.mydomain.com;

    ssl_certificate /etc/letsencrypt/live/mydomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/mydomain.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location / {
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection upgrade;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_redirect off;
        proxy_pass http://proxyws;
    }

}

```

<p><em>Docker-compose</em></p>

```  #############################################################################
  ## IMAGE FOR THE PROXY
  #############################################################################
  proxy:
    container_name: proxy
    build: ./src/Proxy
    restart: always
    env_file: .env
    ports:
      - "8000:8000"

  #############################################################################
  ## IMAGE FOR THE WEBAPP
  #############################################################################
  webapp:
    container_name: webapp
    build: ./src/Webapp
    restart: always
    volumes:
      - ./src/Webapp:/home/app
      - /home/app/.next
      - /home/app/node_modules
    ports:
      - 3000:3000

  #############################################################################
  ## IMAGE THE NGINX & CERTBOT FOR REVERSE PROXY
  #############################################################################
  nginx:
    image: nginx:latest
    container_name: nginx
    volumes:
      - ./data/nginx:/etc/nginx/conf.d
      - ./data/certbot/conf:/etc/letsencrypt
      - ./data/certbot/www:/var/www/certbot
    ports:
      - 80:80
      - 443:443
```

答:
I'm the maintainer of websocket package for fasthttp. The issue is fixed on master branch.

Downdload it with:

go get github.com/fasthttp/websocket@master
```

And try again, please.

If the issue continue, please open an issue in https://github.com/fasthttp/websocket/issues

Soon, I will release a new version.

Title: Websocket on Docker with nginx

Body:
I am trying to build a service with two parts: a backend and a frontend. Both are on a different docker container and are communicating through the docker-compose configuration and a nginx container.

For https access, everything's good, but when I am trying to work with websocket, I have an upgrade error, even if the Nginx configuration got this information

Error message : websocket: the client is not using the websocket protocol:  'upgrade' token not found in 'Connection' header

I am using a fasthttp and fasthttp/websocket for my Golang backend. The code is working on localhost (no nginx configuration), but the combinaison of Docker + nginx seems to break something.
The front-end works with react and is a simple let socket = new WebSocket(wss.mydomain.com/ws/uploadPicture/);

EDIT :

when using ctx.Request.Header.ConnectionUpgrade() just before upgrader.Upgrade, the result is true, but ctx.Response.Header.ConnectionUpgrade() is false

Thank you !

Golang Backend

var upgrader = websocket.FastHTTPUpgrader{
    ReadBufferSize:  1024,
    WriteBufferSize: 1024,
    CheckOrigin: func(ctx *fasthttp.RequestCtx) bool {
        return true
    },
}
func    InitRouter() func(*fasthttp.RequestCtx) {
    router := fasthttprouter.New()

    router.GET("/ws/uploadPicture/", doWS)

    return router.Handler
}
func    doWS(ctx *fasthttp.RequestCtx) {
    err := upgrader.Upgrade(ctx, func(conn *websocket.Conn) {
        //SHOULD DO STUFF
    })
    if (err != nil) {
        logs.Error(err.Error()) //HIT THIS ERROR
        return
    }
}

...
fasthttp.ListenAndServe(`:8000`, InitRouter())

Nginx.conf

#############################################################################
## NGINX CONFIGURATION FOR THE WEBAPP
#############################################################################
upstream webapp {
    server webapp:3000;
    keepalive 4;
}
server {
    listen [::]:443 ssl;
    listen 443 ssl;

    server_name mydomain.com;

    ssl_certificate /etc/letsencrypt/live/mydomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/mydomain.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location / {
        proxy_pass http://webapp;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_redirect off;
    }
}

#############################################################################
## NGINX CONFIGURATION FOR THE PROXY
#############################################################################
upstream proxy {
    server proxy:8000;
    keepalive 4;
}
server {
    listen [::]:443 ssl;
    listen 443 ssl;

    server_name api.mydomain.com;

    ssl_certificate /etc/letsencrypt/live/mydomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/mydomain.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location / {
        add_header 'Access-Control-Allow-Origin' "$http_origin";
        add_header 'Access-Control-Allow-Credentials' true;
        proxy_pass http://proxy;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_redirect off;
    }
}

#############################################################################
## NGINX CONFIGURATION FOR THE PROXY
#############################################################################
upstream proxyws {
    server proxy:8000;
    keepalive 4;
}
server {
    listen [::]:443 ssl;
    listen 443 ssl;

    server_name wss.mydomain.com;

    ssl_certificate /etc/letsencrypt/live/mydomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/mydomain.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location / {
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection upgrade;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_redirect off;
        proxy_pass http://proxyws;
    }

}

Docker-compose

  #############################################################################
  ## IMAGE FOR THE PROXY
  #############################################################################
  proxy:
    container_name: proxy
    build: ./src/Proxy
    restart: always
    env_file: .env
    ports:
      - "8000:8000"

  #############################################################################
  ## IMAGE FOR THE WEBAPP
  #############################################################################
  webapp:
    container_name: webapp
    build: ./src/Webapp
    restart: always
    volumes:
      - ./src/Webapp:/home/app
      - /home/app/.next
      - /home/app/node_modules
    ports:
      - 3000:3000

  #############################################################################
  ## IMAGE THE NGINX & CERTBOT FOR REVERSE PROXY
  #############################################################################
  nginx:
    image: nginx:latest
    container_name: nginx
    volumes:
      - ./data/nginx:/etc/nginx/conf.d
      - ./data/certbot/conf:/etc/letsencrypt
      - ./data/certbot/www:/var/www/certbot
    ports:
      - 80:80
      - 443:443

Body:
I'm the maintainer of websocket package for fasthttp. The issue is fixed on master branch.

Downdload it with:

go get github.com/fasthttp/websocket@master

And try again, please.

If the issue continue, please open an issue in https://github.com/fasthttp/websocket/issues

Soon, I will release a new version.


问:
Possible to interact with a 64-bit COM server (Photoshop) from .NET?
I've been trying to write some code to interact with Photoshop, both by adding a COM reference and by late binding. It took me a while to realise that the code did work, but not with the 64-bit version of Photoshop.

The exception I get with 64-bit Photoshop is as follows:

COMException was unhandled

Retrieving the COM class factory for
  component with CLSID
  {D9389EDE-AEF8-4092-9377-075E94B7CB9A}
  failed due to the following error:
  80080005 Server execution failed
  (Exception from HRESULT: 0x80080005
  (CO_E_SERVER_EXEC_FAILURE)).

Is it possible for my application to communicate with the 64-bit version of Photoshop? Or is it limited to just communicating with the 32-bit version?

I've come across this in one of my numerous attempts to find a solution, but I don't see how I could put the CLSCTX_ACTIVATE_64_BIT_SERVER flag into use with either a COM reference or late binding, well, supposing that it is the solution.

The exception occurs here:

```<code>Type photoshopType = Type.GetTypeFromProgID("Photoshop.Application");
if (photoshopType != null)
{
    object photoshop = Activator.CreateInstance(photoshopType);
</code>```

答:
Assuming from the little information we have:

Quoted from: When CoCreateInstance returns 0x80080005 (CO_E_SERVER_EXEC_FAILURE)

... If the client
  fails to call CoRegisterClassObject()
  from the moment the process was
  started, or fails to call
  CoRegisterClassObjects() at all for
  the given class factory, then the
  client will receive the
  CO_E_SERVER_EXEC_FAILURE error in
  CoCreateInstance(...). This can happen
  for a variety of reasons:

1) The machine has a high CPU load and
  the process takes a long time to start
  and execute the
  CoRegisterClassObjects() in less than
  120 seconds.

2) The COM server doesn't register for
  the right class IDs.

3) The COM server is currently
  stopping and there is a race condition
  between  CoCreateInstance and the COM
  server stopping part.

4) There is a security problem in the
  way the COM server is started (this
  page seems to suggest misspelled
  passwords or lacking the "Login as
  Batch Job" privilege for "Run As.."
  COM servers, but anyway I would
  suggest re-verifying this information
  for your specific configuration)

ContentLicense: CC BY-SA 3.0

Body:
I've been trying to write some code to interact with Photoshop, both by adding a COM reference and by late binding. It took me a while to realise that the code did work, but not with the 64-bit version of Photoshop.

The exception I get with 64-bit Photoshop is as follows:

COMException was unhandled

Retrieving the COM class factory for
  component with CLSID
  {D9389EDE-AEF8-4092-9377-075E94B7CB9A}
  failed due to the following error:
  80080005 Server execution failed
  (Exception from HRESULT: 0x80080005
  (CO_E_SERVER_EXEC_FAILURE)).

Is it possible for my application to communicate with the 64-bit version of Photoshop? Or is it limited to just communicating with the 32-bit version?

I've come across this in one of my numerous attempts to find a solution, but I don't see how I could put the CLSCTX_ACTIVATE_64_BIT_SERVER flag into use with either a COM reference or late binding, well, supposing that it is the solution.

The exception occurs here:

Type photoshopType = Type.GetTypeFromProgID("Photoshop.Application");
if (photoshopType != null)
{
    object photoshop = Activator.CreateInstance(photoshopType);


问:
Excluding LEFT OUTER JOINS in an Oracle SQL QUERY if a COLUMN on base table = 'N'
Below you'll see a simple JOIN statement of 5 base tables, I'm trying to excluded the two LEFT OUTER JOIN statements tables (dandm_emi_cae_statement_links, geod_us_cae_statement_links) from the SQL statement if the column geod_exclude_us_y in the JMD_UDG_DISTRIBUTION table is equal 'N'.

Currently the below statement in the SQL PLAN still looks at these tables, how do I stop it from doing the LEFT OUTER JOIN' if the table JMD_UDG_DISTRIBUTION column geod_exclude_us_y = 'N'?

```<code>SELECT lfu.*
FROM JMD_UDG_DISTRIBUTION jud
JOIN dm_lifeline_file_usages lfu
    ON  lfu.group_id = jud.GROUP_SURR_ID
JOIN dm_lifeline_file_ips lfi
    ON  lfi.usage_group_id = lfu.group_id
    AND lfi.lfu_surr_id = lfu.surr_id
LEFT OUTER JOIN dandm_emi_cae_statement_links dnm
    ON  jud.geod_exclude_us_y = 'Y'
    AND dnm.cae=lfi.cae_number
LEFT OUTER JOIN geod_us_cae_statement_links gucs
    ON  jud.geod_exclude_us_y = 'Y'
    AND gucs.cae_number=lfi.cae_number
</code>```

答:
Of course.  The rules for LEFT JOIN are:

All the rows that match the ON condition.

All rows in the first table when there is no match in the second.

So, a condition on the first table in ON has no impact on the results.  That is not strictly true.  There is a weird sort of impact.  The columns from the second table -- even for otherwise matching rows -- are NULL.

So, you want to filter in the WHERE clause.  Move jud.geod_exclude_us_y = 'Y' from the ON clauses to:

```<code>WHERE jud.geod_exclude_us_y = 'Y'
</code>```

Body:
Below you'll see a simple JOIN statement of 5 base tables, I'm trying to excluded the two LEFT OUTER JOIN statements tables (dandm_emi_cae_statement_links, geod_us_cae_statement_links) from the SQL statement if the column geod_exclude_us_y in the JMD_UDG_DISTRIBUTION table is equal 'N'.

Currently the below statement in the SQL PLAN still looks at these tables, how do I stop it from doing the LEFT OUTER JOIN' if the table JMD_UDG_DISTRIBUTION column geod_exclude_us_y = 'N'?

SELECT lfu.*
FROM JMD_UDG_DISTRIBUTION jud
JOIN dm_lifeline_file_usages lfu
    ON  lfu.group_id = jud.GROUP_SURR_ID
JOIN dm_lifeline_file_ips lfi
    ON  lfi.usage_group_id = lfu.group_id
    AND lfi.lfu_surr_id = lfu.surr_id
LEFT OUTER JOIN dandm_emi_cae_statement_links dnm
    ON  jud.geod_exclude_us_y = 'Y'
    AND dnm.cae=lfi.cae_number
LEFT OUTER JOIN geod_us_cae_statement_links gucs
    ON  jud.geod_exclude_us_y = 'Y'
    AND gucs.cae_number=lfi.cae_number

Body:
Of course.  The rules for LEFT JOIN are:

All the rows that match the ON condition.

All rows in the first table when there is no match in the second.

So, a condition on the first table in ON has no impact on the results.  That is not strictly true.  There is a weird sort of impact.  The columns from the second table -- even for otherwise matching rows -- are NULL.

So, you want to filter in the WHERE clause.  Move jud.geod_exclude_us_y = 'Y' from the ON clauses to:

WHERE jud.geod_exclude_us_y = 'Y'


问:
How can I detect a click in an onTouch listener?
I have a ViewPager inside a ScrollView. I need to be able to scroll horizontally as well as vertically. In order to achieve this had to disable the vertical scrolling whenever my ViewPager is touched (v.getParent().requestDisallowInterceptTouchEvent(true);), so that it can be scrolled horizontally.

But at the same time I need to be able to click the viewPager to open it in full screen mode.

The problem is that onTouch gets called before onClick and my OnClick is never called.

How can I implement both on touch an onClick?

```<code>viewPager.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        System.out.println("TOUCHED ");
        if(event.getAction() == MotionEvent.???){
            //open fullscreen activity
        }
        v.getParent().requestDisallowInterceptTouchEvent(true); //This cannot be removed
        return false;
    }
});

viewPager.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        System.out.println("CLICKED ");
        Intent fullPhotoIntent = new Intent(context, FullPhotoActivity.class);
        fullPhotoIntent.putStringArrayListExtra("imageUrls", imageUrls);
        startActivity(fullPhotoIntent);
    }
});
</code>```

答:
don't try to REINVENT the wheel !

Elegant way to do it :

```<code>public class CustomView extends View {

    private GestureDetectorCompat mDetector;

    public CustomView(Context context) {
        super(context);
        mDetector = new GestureDetectorCompat(context, new MyGestureListener());
    }

    @Override
    public boolean onTouchEvent(MotionEvent event){
        return this.mDetector.onTouchEvent(event);
    }

    class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
        @Override
        public boolean onDown(MotionEvent e) {return true;}

        @Override
        public boolean onSingleTapConfirmed(MotionEvent e) {
            //...... click detected !
            return false;
        }
    }
}
</code>```

Body:
I have a ViewPager inside a ScrollView. I need to be able to scroll horizontally as well as vertically. In order to achieve this had to disable the vertical scrolling whenever my ViewPager is touched (v.getParent().requestDisallowInterceptTouchEvent(true);), so that it can be scrolled horizontally.

But at the same time I need to be able to click the viewPager to open it in full screen mode.

The problem is that onTouch gets called before onClick and my OnClick is never called.

How can I implement both on touch an onClick?

viewPager.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        System.out.println("TOUCHED ");
        if(event.getAction() == MotionEvent.???){
            //open fullscreen activity
        }
        v.getParent().requestDisallowInterceptTouchEvent(true); //This cannot be removed
        return false;
    }
});

viewPager.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        System.out.println("CLICKED ");
        Intent fullPhotoIntent = new Intent(context, FullPhotoActivity.class);
        fullPhotoIntent.putStringArrayListExtra("imageUrls", imageUrls);
        startActivity(fullPhotoIntent);
    }
});

Body:
don't try to REINVENT the wheel !

Elegant way to do it :

public class CustomView extends View {

    private GestureDetectorCompat mDetector;

    public CustomView(Context context) {
        super(context);
        mDetector = new GestureDetectorCompat(context, new MyGestureListener());
    }

    @Override
    public boolean onTouchEvent(MotionEvent event){
        return this.mDetector.onTouchEvent(event);
    }

    class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
        @Override
        public boolean onDown(MotionEvent e) {return true;}

        @Override
        public boolean onSingleTapConfirmed(MotionEvent e) {
            //...... click detected !
            return false;
        }
    }
}


问:
Why is WebElement the same using for each loop Selenium?
I'm trying to get  elements using for each loop, but I'm gettting always the same first element.

Firstly, I'm searching for an element by id.

```<code>WebElement tableId = driver.findElement(By.id("tablepress-6"));
</code>```

Then I'm going to find tr elements by tagName.

```<code> List<WebElement> trElements = tableId.findElements(By.tagName("tr"));
</code>```

And finally using for each loop, I'm trying to get td elements with required fields:

```<code>List<Journal> journalList = new ArrayList<>();
    //...
    for (WebElement element : trElements) {
    String title = element.findElement(By.xpath("//*[@id=\"tablepress-6\"]/tbody/tr/td[3]")).getText();
    //String title = element.findElement(By.xpath("//table[@id='tablepress-6']/tbody/tr/td/a")).getText();
    String city = ...;
    journalList.add(new Journal(title, city));
    }
</code>```

As a result I'm getting:

```<code>Journal{title='Low Temperature Physics', city='...'}
Journal{title='Low Temperature Physics', city='...'}
Journal{title='Low Temperature Physics', city='...'}
Journal{title='Low Temperature Physics', city='...'}
</code>```

Instead of the expected:

```<code>Journal{title='Low Temperature Physics', city='...'}
Journal{title='Ukrainian Journal of Physical Optics', city='...'}
Journal{title='Theoretical and Experimental Chemistry', city='...'}
Journal{title='Kinematics and Physics of Celestial Bodies', city='...'}
</code>```

Here's my HTML code:

```<code><table id=tablepress-6 class="tablepress tablepress-id-6">
    <thead>
        <tr class="row-1 odd">
            <th class=column-1>Sci</th>
            <th class=column-2>Subject area (SJR)</th>
            <th class=column-3>Назва наукового журналу</th>
            <th class=column-4>ISSN (Print&El)</th>
            <th class=column-5>Scopus(SNIP)</th>
            <th class=column-6>WOS_Core</th>
            <th class=column-7>Місто</th>
            <th class=column-8>Шифри 2015</th>
        </tr>
    </thead>
    <tbody class=row-hover>
        <tr class="row-2 even">
            <td class=column-1>П</td>
            <td class=column-2>Physics and astronomy</td>
            <td class=column-3><a href="http://ltp.aip.org/" target=_blank rel="nofollow noopener noreferrer">Low Temperature Physics</a></td>
            <td class=column-4>1063-777X
                <br/> 1090-6517
                <br/>
            </td>
            <td class=column-5><a href="https://www.scopus.com/sourceid/13789" target=_blank rel="nofollow noopener noreferrer">0,617</a>
                <br/> 1997-2019
            </td>
            <td class=column-6><a href="http://ip-science.thomsonreuters.com/cgi-bin/jrnlst/jlresults.cgi?PC=MASTER&ISSN=1063-777X" target=_blank rel="nofollow noopener noreferrer">SCIE (0,860)</a>
                <br/> 1997-2019
            </td>
            <td class=column-7>Харків /
                <br/> Нью-Йорк
            </td>
            <td class=column-8>10; 13</td>
        </tr>
        <tr class="row-3 odd">
            <td class=column-1>П</td>
            <td class=column-2>Physics and astronomy</td>
            <td class=column-3><a href="http://www.ifo.lviv.ua/journal/" target=_blank rel="nofollow noopener noreferrer">Ukrainian Journal of Physical Optics</a>
                <br/> Український журнал фізичної оптики</td>
            <td class=column-4>1609-1833
                <br/> 1816-2002
                <br/>
            </td>
            <td class=column-5><a href="https://www.scopus.com/sourceid/11400153315" target=_blank rel="nofollow noopener noreferrer">0,593</a>
                <br/> 2000-2019
            </td>
            <td class=column-6><a href="http://ip-science.thomsonreuters.com/cgi-bin/jrnlst/jlresults.cgi?PC=MASTER&ISSN=1609-1833" target=_blank rel="nofollow noopener noreferrer">SCIE (0,488)</a>
                <br/> 2008-2019
            </td>
            <td class=column-7>Київ</td>
            <td class=column-8>10</td>
        </tr>
        <tr class="row-4 even">
            <td class=column-1>П</td>
            <td class=column-2>Chemistry</td>
            <td class=column-3><a href="http://link.springer.com/journal/11237" target=_blank rel="nofollow noopener noreferrer">Theoretical and Experimental Chemistry</a></td>
            <td class=column-4>0040-5760
                <br/> 1573-935X
                <br/>
            </td>
            <td class=column-5><a href="https://www.scopus.com/sourceid/21969" target=_blank rel="nofollow noopener noreferrer">0,198</a>
                <br/> 1967-2019
            </td>
            <td class=column-6><a href="http://ip-science.thomsonreuters.com/cgi-bin/jrnlst/jlresults.cgi?PC=MASTER&ISSN=0040-5760" target=_blank rel="nofollow noopener noreferrer">SCIE (0,878)</a>
                <br/> 2008-2019
            </td>
            <td class=column-7>Київ /
                <br/> Нью-Йорк
            </td>
            <td class=column-8>10; 16</td>
        </tr>
        <tr class="row-5 odd">
            <td class=column-1>П</td>
            <td class=column-2>Earth and planetary sciences; Physics and Astronomy</td>
            <td class=column-3><a href="http://www.allertonpress.com/journals/kin.htm" target=_blank rel="nofollow noopener noreferrer">Kinematics and Physics of Celestial Bodies</a>
                <br/> Кінематика і фізика небесних тіл</td>
            <td class=column-4>0884-5913
                <br/> 1934-8401
                <br/>
            </td>
            <td class=column-5><a href="https://www.scopus.com/sourceid/19700173017" target=_blank rel="nofollow noopener noreferrer">0,432</a>
                <br/> 2009-2019
            </td>
            <td class=column-6><a href="http://ip-science.thomsonreuters.com/cgi-bin/jrnlst/jlresults.cgi?PC=MASTER&ISSN=0884-5913" target=_blank rel="nofollow noopener noreferrer">SCIE (0,654)</a>
                <br/> 2008-2019
            </td>
            <td class=column-7>Київ /
                <br/> Нью-Йорк
            </td>
            <td class=column-8>10</td>
        </tr>
        <tr class="row-6 even">
            <td class=column-1>П</td>
            <td class=column-2>Biochemistry, genetics and molecular biology; Medicine</td>
            <td class=column-3><a href="https://link.springer.com/journal/11956" target=_blank rel="nofollow noopener noreferrer">Cytology and Genetics</a>
                <br/> Цитологія і генетика</td>
            <td class=column-4>0564-3783
                <br/> 0095-4527
                <br/>
            </td>
            <td class=column-5><a href="https://www.scopus.com/sourceid/19061" target=_blank rel="nofollow noopener noreferrer">0,229</a>
                <br/> 2009-2019
            </td>
            <td class=column-6><a href="http://ip-science.thomsonreuters.com/cgi-bin/jrnlst/jlresults.cgi?PC=MASTER&ISSN=0095-4527" target=_blank rel="nofollow noopener noreferrer">SCIE (0,239)</a>
                <br/> 2007-2019
            </td>
            <td class=column-7>Київ /
                <br/> Нью-Йорк
            </td>
            <td class=column-8>09; 22</td>
        </tr>
     //...
    </tbody>
</table>
</code>```

Am I missing something here? Thanks in advance.

答:
try below XPath

........................

```<code>List<WebElement> trElements = tableId.findElements(By.xpath("./tbody/tr"));
</code>```

.......................

```<code>String title = element.findElement(By.xpath("./td[3]")).getText();
</code>```

Body:
I'm trying to get  elements using for each loop, but I'm gettting always the same first element.

Firstly, I'm searching for an element by id.

WebElement tableId = driver.findElement(By.id("tablepress-6"));

Then I'm going to find tr elements by tagName.

 List<WebElement> trElements = tableId.findElements(By.tagName("tr"));

And finally using for each loop, I'm trying to get td elements with required fields:

List<Journal> journalList = new ArrayList<>();
    //...
    for (WebElement element : trElements) {
    String title = element.findElement(By.xpath("//*[@id=\"tablepress-6\"]/tbody/tr/td[3]")).getText();
    //String title = element.findElement(By.xpath("//table[@id='tablepress-6']/tbody/tr/td/a")).getText();
    String city = ...;
    journalList.add(new Journal(title, city));
    }

As a result I'm getting:

Journal{title='Low Temperature Physics', city='...'}
Journal{title='Low Temperature Physics', city='...'}
Journal{title='Low Temperature Physics', city='...'}
Journal{title='Low Temperature Physics', city='...'}

Instead of the expected:

Journal{title='Low Temperature Physics', city='...'}
Journal{title='Ukrainian Journal of Physical Optics', city='...'}
Journal{title='Theoretical and Experimental Chemistry', city='...'}
Journal{title='Kinematics and Physics of Celestial Bodies', city='...'}

Here's my HTML code:

            Sci
            Subject area (SJR)
            Назва наукового журналу
            ISSN (Print&El)
            Scopus(SNIP)
            WOS_Core
            Місто
            Шифри 2015

            П
            Physics and astronomy
            Low Temperature Physics
            1063-777X

 1090-6517

            0,617

 1997-2019

            SCIE (0,860)

 1997-2019

            Харків /

 Нью-Йорк

            10; 13

            П
            Physics and astronomy
            Ukrainian Journal of Physical Optics

 Український журнал фізичної оптики
            1609-1833

 1816-2002

            0,593

 2000-2019

            SCIE (0,488)

 2008-2019

            Київ
            10

            П
            Chemistry
            Theoretical and Experimental Chemistry
            0040-5760

 1573-935X

            0,198

 1967-2019

            SCIE (0,878)

 2008-2019

            Київ /

 Нью-Йорк

            10; 16

            П
            Earth and planetary sciences; Physics and Astronomy
            Kinematics and Physics of Celestial Bodies

 Кінематика і фізика небесних тіл
            0884-5913

 1934-8401

            0,432

 2009-2019

            SCIE (0,654)

 2008-2019

            Київ /

 Нью-Йорк

            10

            П
            Biochemistry, genetics and molecular biology; Medicine
            Cytology and Genetics

 Цитологія і генетика
            0564-3783

 0095-4527

            0,229

 2009-2019

            SCIE (0,239)

 2007-2019

            Київ /

 Нью-Йорк

            09; 22

     //...

Am I missing something here? Thanks in advance.

Body:
try below XPath

........................

List<WebElement> trElements = tableId.findElements(By.xpath("./tbody/tr"));

.......................

String title = element.findElement(By.xpath("./td[3]")).getText();


问:
Sass @extend to consider imported css during build
I have a global CSS file that contains all generic CSS.

I want to be able to extend all the classes present in this global CSS file in any of my SCSS files.

Right now it throws an error .xyz class does not exist and build fails. I tried importing this file but still build fails.

Adding !options next to class is one way for the build to pass but is there any other better way?

Bit more context for Vue users. I use VueCli3. I use

答:
Using @import CSS file into SCSS file not possible to @extend any class.

But you can follow below steps for extends class from your pure css code.

Convert .css file into .scss.

import that global.scss file into another .scss file.

Then after you can use @extend for extend class in new file.

If your file have more then 1k line of code then it will get trouble for extend class.


问:
Azure DevOps API work with releases states
I want to get releases, which state is only
in progress, but when I send request https://vsrm.dev.azure.com/{organization}/{project}/_apis/release/releases?definitionId={definitionId}&api-version=5.1 to get all releases and see, which field is responsible for release state I see, that all releases have status active.

I thought I must use https://vsrm.dev.azure.com/{organization}/{project}/_apis/release/releases?definitionId={definitionId}&statusFilter=active&api-version=5.1, but that is wrong way for my target task.

What should I use? Thanks you in advance!

答:
That's because you're looking at the wrong API. You need to use the deployments API and specify deploymentStatus for querying the status of deployments.

The API you're using queries the overall status of a given release, not the individual stages. The JSON returned contains information about the stages, but you can't filter the stages based on their current status with that API.


问:
If statement searches values only in specific order
I am loading two JSON files and iterate them in order to replace values from of the JSON's using references from the other.

```<code>{"Target":{
 "TV_1":{
                "id":"001_101_001",
                "query_name":"tvchview",
                "param":{"$source":"tv","$channel":["RTL","rrr"]},
                "target_group_type":"multiple",
                "mapping_list":{}
            },
  "TV_2":{
                "id":"001_101_003",
                "query_name":"tvch_1hr",
                "param":{"$source":"tv"},
                "target_group_type":"multiple",
                "mapping_list":{}
            }}}

{"Target_queries": {
"tvchview":{
             "name":"tvchview",
             "description":"Select panelists that have watched a tv channel at least one time.",
             "sql":"SELECT DISTINCT pnr, channel AS value FROM $source WHERE channel IN ( $channel ) AND slice_start >= $startdate AND slice_start <= $enddate ;"
               },
  "tvch_1hr":{
             "name":"tvch_1hr",
             "description":"Select panelists that have watched tv channels for at least one hour.",
             "sql":"SELECT pnr, channel AS value FROM $source WHERE slice_start >= $startdate AND slice_start <= $enddate AND duration >= 3600 AND channel != '-' GROUP BY pnr, channel;"
              }}}
</code>```

My code works when the JSON files look like this, but when I switch the places of TV_1 and TV_2 (TV_2 goes in the place of TV_1) my code doesnt return anything, meaning it doesnt match the two dicts by name and query_name.

This is the part of code where i replace the values:

```<code>for (k, v), (k1, v1) in zip(params_to_replace.items(), queries.items()):
    if v1['name'] in v['query_name']:
        params = v['param']
        split_queries = v1['sql'].split()
        final_string = ' '.join(str(params.get(word, word)) for word in split_queries)
        final_string = re.sub(r'(\[)|(\])', '', final_string)
        replaced_queries[k] = final_string
    else:
        pass
</code>```

v1['name'] is where the name of the queries are ("name":"tvchview") and v['query_name'] is the names, but in the other JSON ("query_name":"tvchview"). When I switch again the structure of the queries it works again. Somehow the if statement search only when the order of the query names matches on both files. Any ideas?

答:
I think the problem is with the zip statement, which only joins two entries. Instead you want to test all possible combinations. For this you can use itertools.product

The corrected code:

import re
import itertools
params_to_replace = {
    "TV_2": {
        "id": "001_101_003",
        "query_name": "tvch_1hr",
        "param": {"$source": "tv"},
        "target_group_type": "multiple",
        "mapping_list": {}
    },
 "TV_1":{
                "id":"001_101_001",
                "query_name":"tvchview",
                "param":{"$source":"tv","$channel":["RTL","rrr"]},
                "target_group_type":"multiple",
                "mapping_list":{}
            },
}

queries = {
"tvchview":{
             "name":"tvchview",
             "description":"Select panelists that have watched a tv channel at least one time.",
             "sql":"SELECT DISTINCT pnr, channel AS value FROM $source WHERE channel IN ( $channel ) AND slice_start >= $startdate AND slice_start <= $enddate ;"
               },
  "tvch_1hr":{
             "name":"tvch_1hr",
             "description":"Select panelists that have watched tv channels for at least one hour.",
             "sql":"SELECT pnr, channel AS value FROM $source WHERE slice_start >= $startdate AND slice_start <= $enddate AND duration >= 3600 AND channel != '-' GROUP BY pnr, channel;"
              }}

replaced_queries = {}

for (k, v), (k1, v1) in itertools.product(params_to_replace.items(), queries.items()):
    if v1['name'] in v['query_name']:
        params = v['param']
        split_queries = v1['sql'].split()
        final_string = ' '.join(str(params.get(word, word)) for word in split_queries)
        final_string = re.sub(r'(\[)|(\])', '', final_string)
        replaced_queries[k] = final_string
    else:
        pass

print(replaced_queries)
```

{'TV_2': "SELECT pnr, channel AS value FROM tv WHERE slice_start >= $startdate AND slice_start <= $enddate AND duration >= 3600 AND channel != '-' GROUP BY pnr, channel;", 'TV_1': "SELECT DISTINCT pnr, channel AS value FROM tv WHERE channel IN ( 'RTL', 'rrr' ) AND slice_start >= $startdate AND slice_start <= $enddate ;"}

Body:
I am loading two JSON files and iterate them in order to replace values from of the JSON's using references from the other.

{"Target":{
 "TV_1":{
                "id":"001_101_001",
                "query_name":"tvchview",
                "param":{"$source":"tv","$channel":["RTL","rrr"]},
                "target_group_type":"multiple",
                "mapping_list":{}
            },
  "TV_2":{
                "id":"001_101_003",
                "query_name":"tvch_1hr",
                "param":{"$source":"tv"},
                "target_group_type":"multiple",
                "mapping_list":{}
            }}}

{"Target_queries": {
"tvchview":{
             "name":"tvchview",
             "description":"Select panelists that have watched a tv channel at least one time.",
             "sql":"SELECT DISTINCT pnr, channel AS value FROM $source WHERE channel IN ( $channel ) AND slice_start >= $startdate AND slice_start <= $enddate ;"
               },
  "tvch_1hr":{
             "name":"tvch_1hr",
             "description":"Select panelists that have watched tv channels for at least one hour.",
             "sql":"SELECT pnr, channel AS value FROM $source WHERE slice_start >= $startdate AND slice_start <= $enddate AND duration >= 3600 AND channel != '-' GROUP BY pnr, channel;"
              }}}

My code works when the JSON files look like this, but when I switch the places of TV_1 and TV_2 (TV_2 goes in the place of TV_1) my code doesnt return anything, meaning it doesnt match the two dicts by name and query_name.

This is the part of code where i replace the values:

for (k, v), (k1, v1) in zip(params_to_replace.items(), queries.items()):
    if v1['name'] in v['query_name']:
        params = v['param']
        split_queries = v1['sql'].split()
        final_string = ' '.join(str(params.get(word, word)) for word in split_queries)
        final_string = re.sub(r'(\[)|(\])', '', final_string)
        replaced_queries[k] = final_string
    else:
        pass

v1['name'] is where the name of the queries are ("name":"tvchview") and v['query_name'] is the names, but in the other JSON ("query_name":"tvchview"). When I switch again the structure of the queries it works again. Somehow the if statement search only when the order of the query names matches on both files. Any ideas?

Body:
I think the problem is with the zip statement, which only joins two entries. Instead you want to test all possible combinations. For this you can use itertools.product

The corrected code:

import re
import itertools
params_to_replace = {
    "TV_2": {
        "id": "001_101_003",
        "query_name": "tvch_1hr",
        "param": {"$source": "tv"},
        "target_group_type": "multiple",
        "mapping_list": {}
    },
 "TV_1":{
                "id":"001_101_001",
                "query_name":"tvchview",
                "param":{"$source":"tv","$channel":["RTL","rrr"]},
                "target_group_type":"multiple",
                "mapping_list":{}
            },
}

queries = {
"tvchview":{
             "name":"tvchview",
             "description":"Select panelists that have watched a tv channel at least one time.",
             "sql":"SELECT DISTINCT pnr, channel AS value FROM $source WHERE channel IN ( $channel ) AND slice_start >= $startdate AND slice_start <= $enddate ;"
               },
  "tvch_1hr":{
             "name":"tvch_1hr",
             "description":"Select panelists that have watched tv channels for at least one hour.",
             "sql":"SELECT pnr, channel AS value FROM $source WHERE slice_start >= $startdate AND slice_start <= $enddate AND duration >= 3600 AND channel != '-' GROUP BY pnr, channel;"
              }}

replaced_queries = {}

for (k, v), (k1, v1) in itertools.product(params_to_replace.items(), queries.items()):
    if v1['name'] in v['query_name']:
        params = v['param']
        split_queries = v1['sql'].split()
        final_string = ' '.join(str(params.get(word, word)) for word in split_queries)
        final_string = re.sub(r'(\[)|(\])', '', final_string)
        replaced_queries[k] = final_string
    else:
        pass

print(replaced_queries)

{'TV_2': "SELECT pnr, channel AS value FROM tv WHERE slice_start >= $startdate AND slice_start <= $enddate AND duration >= 3600 AND channel != '-' GROUP BY pnr, channel;", 'TV_1': "SELECT DISTINCT pnr, channel AS value FROM tv WHERE channel IN ( 'RTL', 'rrr' ) AND slice_start >= $startdate AND slice_start <= $enddate ;"}


问:
ajaxtoolkit modal popup Child window should return row value of gridview to the parent page
i'm new to ajax, i'm using ajaxtoolkit modalpopup here's the case

using an image button in a girdview on the parentpage modalpopup(child) is opened which has a girdview, i want to return the vale of the row of gridview from the childpage to the parent page textbox, modalpopup panel is on the same parent page .

Help me out...how to overcome this problem,

Thanks in Adv.

答: Please paste code, also modal pop up and controls will be the same page, so you can access directly, please paste code where you are getting error.  </p>


问:
Collapsing three columns with bootstrap
I am trying to make three tabs with cross-referencing with one tab visible at the time. I was using the bootstrap v4 collapse scheme with functionality supported by jQuery. Here is the example: https://jsfiddle.net/omjvhurd/30/

$(document).ready(function() {

  $("#Tab2_t1").click(function() {
  $('#t1').collapse('hide');
  $('#t1').on('hidden.bs.collapse', function () {
   $('#t2').collapse('show');
  });
 })

  $("#Tab3_t1").click(function() {
  $('#t1').collapse('hide');
  $('#t1').on('hidden.bs.collapse', function () {
   $('#t3').collapse('show');
  });
 })

  $("#Tab1_t2").click(function() {
  $('#t2').collapse('hide');
  $('#t2').on('hidden.bs.collapse', function () {
   $('#t1').collapse('show');
  });
 })

  $("#Tab3_t2").click(function() {
  $('#t2').collapse('hide');
  $('#t2').on('hidden.bs.collapse', function () {
   $('#t3').collapse('show');
  });
 })

  $("#Tab1_t3").click(function() {
  $('#t3').collapse('hide');
  $('#t3').on('hidden.bs.collapse', function () {
   $('#t1').collapse('show');
  });
 })

  $("#Tab2_t3").click(function() {
  $('#t3').collapse('hide');
  $('#t3').on('hidden.bs.collapse', function () {
   $('#t2').collapse('show');
  });
 })
});```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">
  <div class="row">
    <div class="col-sm-9 collapse show" id="t1">
      Tab 2
      Tab 3
    </div>

    <div class="col-sm-9 collapse" id="t2">
      Tab 1
      Tab 3
    </div>

    <div class="col-sm-9 collapse" id="t3">
      Tab 1
      Tab 2
    </div>
  </div>
</div></code>```

The problem is that when I click Tab 2, Tab 1 and then Tab 3, I see two tabs displayed simultaneously. Any idea where the error comes from?

答:
Simply hide .collapse and show the tab id on your click functions:

```<code>$(document).ready(function() {

  $("#Tab2_t1").click(function() {
        $('.collapse').collapse('hide');
        $('#t2').collapse('show');
    })

  $("#Tab3_t1").click(function() {
        $('.collapse').collapse('hide');
        $('#t3').collapse('show');
    })

  $("#Tab1_t2").click(function() {
        $('.collapse').collapse('hide');
        $('#t1').collapse('show');
    })

  $("#Tab3_t2").click(function() {
        $('.collapse').collapse('hide');
        $('#t3').collapse('show');
    })

  $("#Tab1_t3").click(function() {
        $('.collapse').collapse('hide');
        $('#t1').collapse('show');
    })

  $("#Tab2_t3").click(function() {
        $('.collapse').collapse('hide');
        $('#t2').collapse('show');
    })
});
</code>```

Here's the fiddle: https://jsfiddle.net/Maro94/cr6d9L03/3/

Title: Collapsing three columns with bootstrap

Body:
I am trying to make three tabs with cross-referencing with one tab visible at the time. I was using the bootstrap v4 collapse scheme with functionality supported by jQuery. Here is the example: https://jsfiddle.net/omjvhurd/30/

$(document).ready(function() {

  $("#Tab2_t1").click(function() {
  $('#t1').collapse('hide');
  $('#t1').on('hidden.bs.collapse', function () {
   $('#t2').collapse('show');
  });
 })

  $("#Tab3_t1").click(function() {
  $('#t1').collapse('hide');
  $('#t1').on('hidden.bs.collapse', function () {
   $('#t3').collapse('show');
  });
 })

  $("#Tab1_t2").click(function() {
  $('#t2').collapse('hide');
  $('#t2').on('hidden.bs.collapse', function () {
   $('#t1').collapse('show');
  });
 })

  $("#Tab3_t2").click(function() {
  $('#t2').collapse('hide');
  $('#t2').on('hidden.bs.collapse', function () {
   $('#t3').collapse('show');
  });
 })

  $("#Tab1_t3").click(function() {
  $('#t3').collapse('hide');
  $('#t3').on('hidden.bs.collapse', function () {
   $('#t1').collapse('show');
  });
 })

  $("#Tab2_t3").click(function() {
  $('#t3').collapse('hide');
  $('#t3').on('hidden.bs.collapse', function () {
   $('#t2').collapse('show');
  });
 })
});

<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet"/>

      Tab 2
      Tab 3

      Tab 1
      Tab 3

      Tab 1
      Tab 2

The problem is that when I click Tab 2, Tab 1 and then Tab 3, I see two tabs displayed simultaneously. Any idea where the error comes from?

Body:
Simply hide .collapse and show the tab id on your click functions:

$(document).ready(function() {

  $("#Tab2_t1").click(function() {
        $('.collapse').collapse('hide');
        $('#t2').collapse('show');
    })

  $("#Tab3_t1").click(function() {
        $('.collapse').collapse('hide');
        $('#t3').collapse('show');
    })

  $("#Tab1_t2").click(function() {
        $('.collapse').collapse('hide');
        $('#t1').collapse('show');
    })

  $("#Tab3_t2").click(function() {
        $('.collapse').collapse('hide');
        $('#t3').collapse('show');
    })

  $("#Tab1_t3").click(function() {
        $('.collapse').collapse('hide');
        $('#t1').collapse('show');
    })

  $("#Tab2_t3").click(function() {
        $('.collapse').collapse('hide');
        $('#t2').collapse('show');
    })
});

Here's the fiddle: https://jsfiddle.net/Maro94/cr6d9L03/3/


问:
Retrive a mail from gmail inbox for a particular subject
I have a scenario where I have to read a mail sent out by a X person with a specific subject, which i will be receiving on a daily basis.

Is there any JAVA Gmail APi provided by google to retrieve the recent mail that i have received.

And also is there a way to retrieve the mail for a given date?

答:
Yes there's a Gmail API and it has a Java client library, you can check the Quickstart to get used to it.

Now, for retrieving a list of mails you will need to use the Users.messages: list endpoint ( There's also a Java example on how to use that endpoint). Answering your question about retrieving certain emails, you will need to use the q parameter and set the values there as if you would be searching an email in the gmail search bar. I will leave you an example that you can try using the Try this API:

List emails from certain user and date.

Notice

You will only get the email's IDs, for getting more info about an email, you will have to use the Users.messages: get endpoint.


问:
Multi region active-active using S3 bucket in each region
I'm trying to design an architecture for a "simple" problem but for the moment I did not found the solution.

The problem:

I have a S3 bucket (one in each region with bucket replication in order to have the same thing in each bucket) and I would like to have a CloudFront in front of it to cache objects.

My need: to have the lowest latency for each user in the world when displaying an object from S3 bucket.

I wanted to have a CloudFront distribution in front of each S3 bucket and a Route53 to route based on the latency to the nearest CF. The problem is that we cannot have many distribution for the same cname.

Here bellow the architecture I have so far (which is not good).

Any idea how to achieve this ?

Thanks.

C.C.

答:
The AWS solutions has launched new solution to address the S3 replication across the regions.

For example, you can create objects in Oregon, rename them in Singapore, and delete them in Dublin, and the changes are replicated to all other regions. This solution is designed for workloads that can tolerate lost events and variations in replication speed.

https://aws.amazon.com/solutions/multi-region-asynchronous-object-replication-solution/


问:
Datatables destroy function error
I'm using datatables.js for creating a report table. In my report page there are some filters. When apply any of filters my service returns data that has different column count. Because of this I'm destroying and recreating table. But an error occurs like Unable to get property 'style' of undefined or null reference.

```<code>          var  htmlTable = "<table class='display responsive no-wrap cell-border compact' style='margin: 0 !important' width='100%' id='policyTable'>" +
            "<thead>" +
            "<tr class='cell-border custom-header-footer tableHeaders' id='tableHeaders'>" +
            "<th>Policy Details</th>" +
            "</tr>" +
            "</thead>" +
            "</table>";

    function InitAndLoadTableData(tableData, tableId, exportTitle) {

        if ($.fn.DataTable.fnIsDataTable("#" + tableId)) {
            var oldTable = $("#" + tableId).DataTable();
            oldTable.destroy(true);
            $("#divFor_" + tableId).append(htmlTable);
        }

        var table = $('#' + tableId)
            .DataTable({
                data: tableData,
                dom: "<'row' <'col-md-12'B>><'table-scrollable't><'row'<'col-md-5 col-sm-12'i><'col-md-7 col-sm-12'p>>",
                "searching": false,
                "paging": false,
                "info": false,
                "ordering": false,
                //destroy: true,
                responsive: true,
                processing: false,
                columns: tableColumns,
                buttons: [
                    { extend: 'copy', className: 'btn red btn-outline', title: exportTitle },
                    { extend: 'pdf', className: 'btn green btn-outline', title: exportTitle },
                    { extend: 'excel', className: 'btn yellow btn-outline', title: exportTitle },
                    { extend: 'csv', className: 'btn purple btn-outline', title: exportTitle }
                ]
            });

        table.buttons().container().appendTo($('.col-md-12:eq(0)', table.table().container()));

    }
</code>```

答:
I ran into the same issue - the intent was the same as the columns are dynamic.

I finally had to use the following code:

```<code>let table = $("#table-id").DataTable();
table.clear();
table.destroy();

// Once you know the columns, recreate by calling DataTable initializer
// Another important part - I do remove and recreate <th> based on received columns
// or we get a weird 'style' error because of mismatch between data and table columns.
</code>```

The table.clear() call was the missing piece - without it, the existing HTML was not being removed. Passing destroy: true within DataTable constructor was useless and table.destroy did the trick.

Title: Datatables destroy function error

Body:
I'm using datatables.js for creating a report table. In my report page there are some filters. When apply any of filters my service returns data that has different column count. Because of this I'm destroying and recreating table. But an error occurs like Unable to get property 'style' of undefined or null reference.

          var  htmlTable = "
" +
            "
" +
            "
" +
            "Policy Details	" +
            "
" +
            "
" +
            "
";

    function InitAndLoadTableData(tableData, tableId, exportTitle) {

        if ($.fn.DataTable.fnIsDataTable("#" + tableId)) {
            var oldTable = $("#" + tableId).DataTable();
            oldTable.destroy(true);
            $("#divFor_" + tableId).append(htmlTable);
        }

        var table = $('#' + tableId)
            .DataTable({
                data: tableData,
                dom: "<'row' <'col-md-12'B>><'table-scrollable't><'row'<'col-md-5 col-sm-12'i><'col-md-7 col-sm-12'p>>",
                "searching": false,
                "paging": false,
                "info": false,
                "ordering": false,
                //destroy: true,
                responsive: true,
                processing: false,
                columns: tableColumns,
                buttons: [
                    { extend: 'copy', className: 'btn red btn-outline', title: exportTitle },
                    { extend: 'pdf', className: 'btn green btn-outline', title: exportTitle },
                    { extend: 'excel', className: 'btn yellow btn-outline', title: exportTitle },
                    { extend: 'csv', className: 'btn purple btn-outline', title: exportTitle }
                ]
            });

        table.buttons().container().appendTo($('.col-md-12:eq(0)', table.table().container()));

    }

Body:
I ran into the same issue - the intent was the same as the columns are dynamic.

I finally had to use the following code:

let table = $("#table-id").DataTable();
table.clear();
table.destroy();

// Once you know the columns, recreate by calling DataTable initializer
// Another important part - I do remove and recreate <th> based on received columns
// or we get a weird 'style' error because of mismatch between data and table columns.

The table.clear() call was the missing piece - without it, the existing HTML was not being removed. Passing destroy: true within DataTable constructor was useless and table.destroy did the trick.


问:
Can't ssh using the URI form
I have an ssh server on my local machine and I'm trying to connect to it:

ssh myuser@localhost -p 8080 This works.

ssh ssh://myuser@localhost:8080 This doesn't.

I read that ssh allows the uri form, so why isn't it working? What am I doing wrong?

答:
The OpenSSH command-line utilities added the ability to specify a URI on the command line with version 7.7:

ssh(1)/scp(1)/sftp(1): Add URI support to ssh, sftp and scp, e.g.
  ssh://user@host or sftp://user@host/path.  Additional connection
  parameters described in draft-ietf-secsh-scp-sftp-ssh-uri-04 are not
  implemented since the ssh fingerprint format in the draft uses the
  deprecated MD5 hash with no way to specify the any other algorithm.

You might be using an older version of ssh which doesn't accept URIs on the command line.

Title: Can't ssh using the URI form


问:
Using argparse.subparser with boolean values
I've read through the Python argparse documentation several times and must be missing something huge.  I'm trying to add a makefile like syntax onto my cli tool, but despite the --help flag showing me the expected behavior the execution of it errors out:

test.py

import argparse
import os

def main():
    parser = argparse.ArgumentParser()
    subparsers = parser.add_subparsers()

    make_subparser = subparsers.add_parser("make")
    make_subparser.add_argument("update", action="store_false", help="Runs all make targets")
    make_subparser.add_argument("clean", action="store_false", help="Cleans up everything done previously")

    args = parser.parse_args()

    if args.update:
        os.system("touch test.txt")

    elif args.clean:
        os.system("rm test.txt")

    else:
        print("Bad args, see: python test.py make --help.")

if __name__ == "__main__":
    main()
```

<p>Then in my terminal:</p>

<pre class="lang-sh prettyprint-override"><code>$> python test.py make --help
usage: test.py make [-h]

positional arguments:
  update      Runs all make targets

$> python test.py make update
usage: test.py [-h] {make} ...
test.py: error: unrecognized arguments: update
$> # this should make a file
$>
$> python test.py make clean
usage: test.py [-h] {make} ...
test.py: error: unrecognized arguments: clean
$> # this should delete the file

</code>```

This works fine if I swap out the action="store_false" for action="store_true", but there's a dozen make commands so I only want to run the one that the user adds in the cli, if they try to enter any more it should exit.

答:
In the POSIX (and POSIX adjacent) world, boolean arguments are handled as flags which are passed via the command line as --argument. What you want isn’t boolean arguments (and that isn’t how Make treats them either), it’s simply a variable number of positional arguments, i.e. having arity *:

```<code>make_subparser.add_argument('targets', nargs='*')
</code>```

This would be closest to how Make operates. However, from your command line it looks more like what you actually want is nested subcommands.

Body:
I've read through the Python argparse documentation several times and must be missing something huge.  I'm trying to add a makefile like syntax onto my cli tool, but despite the --help flag showing me the expected behavior the execution of it errors out:

test.py

import argparse
import os

def main():
    parser = argparse.ArgumentParser()
    subparsers = parser.add_subparsers()

    make_subparser = subparsers.add_parser("make")
    make_subparser.add_argument("update", action="store_false", help="Runs all make targets")
    make_subparser.add_argument("clean", action="store_false", help="Cleans up everything done previously")

    args = parser.parse_args()

    if args.update:
        os.system("touch test.txt")

    elif args.clean:
        os.system("rm test.txt")

    else:
        print("Bad args, see: python test.py make --help.")

if __name__ == "__main__":
    main()

Then in my terminal:

$> python test.py make --help
usage: test.py make [-h]

positional arguments:
  update      Runs all make targets

$> python test.py make update
usage: test.py [-h] {make} ...
test.py: error: unrecognized arguments: update
$> # this should make a file
$>
$> python test.py make clean
usage: test.py [-h] {make} ...
test.py: error: unrecognized arguments: clean
$> # this should delete the file

This works fine if I swap out the action="store_false" for action="store_true", but there's a dozen make commands so I only want to run the one that the user adds in the cli, if they try to enter any more it should exit.

Body:
In the POSIX (and POSIX adjacent) world, boolean arguments are handled as flags which are passed via the command line as --argument. What you want isn’t boolean arguments (and that isn’t how Make treats them either), it’s simply a variable number of positional arguments, i.e. having arity *:

make_subparser.add_argument('targets', nargs='*')

This would be closest to how Make operates. However, from your command line it looks more like what you actually want is nested subcommands.


问:
Export Google sheet Chart as an image
Would you please help on how to export a chart to a image using google script.

I wrote this code but it doesn't work. I'm worrying that the API getAs is deprecated.

```<code>function TestEmailCharts(){
    var sheet = SpreadsheetApp.getActiveSheet();

  var charts = sheet.getCharts();

  if(charts.length!=0)
  {
  var chartBlobs=new Array(charts.length);
  var emailBody="Charts<br>";
  var emailImages={};
  for(var i=0;i<charts.length;i++){
    chartBlobs[i]= charts[i].getAs("image/jpeg").setName("chartBlob"+i);
    emailBody= emailBody + "<img src='cid:chart"+i+"'><br>";
    emailImages["chart"+i]= chartBlobs[i];
  }

  MailApp.sendEmail({
    to: "email@gmail.com",
    subject: "test2",
    htmlBody: emailBody,
    inlineImages:emailImages});
  }
}
</code>```

To reproduce the problem,  create a Google spread sheet
Create a simple chart with some data.

Add this code to scripts.
Replace email@gmail.com with your email

Normally you should receive an email with chart image
But the problem is that you will receive a email with black image.

Best regards.

答:
Exporting a Google sheet chart as an image

By Email:
First create the chart and then get its blob. Then send the blob as attachment.

```<code>function createPieChart(){
  var sheet = SpreadsheetApp.openById("<ID>").getSheetByName("<SheetName>");
  var chartBuilder = sheet.newChart()
      .asPieChart()
      .set3D()
      .addRange(sheet.getRange("A20").getDataRegion())
      .setPosition(16, 5, 0, 0)
      .setOption('title', "Total hour split in 2020");
  var blob = chartBuilder.build().getBlob();
  sendMail(blob);
}

function sendMail(img){
  MailApp.sendEmail({
    to: "john@domain.com",
    subject: "test",
    htmlBody: "fair enough",
    attachments: [img]}); //If this gives you problems, replace img with img.getAs(MimeType.JPEG)
}
</code>```

To another spreadsheet (different from where the source data for the chart is):

Similar way, create the chart and then insert the blob as an image in the destination sheet:

```<code>function createPieChart(){
  var srcSheet = SpreadsheetApp.openById("<ID>").getSheetByName("<SheetName>");
  var destSheet = SpreadsheetApp.openById("<ID>").getSheetByName("<SheetName>");
   var chartBuilder = srcSheet.newChart()
      .asPieChart()
      .set3D()
      .addRange(sheet.getRange("A20").getDataRegion())
      .setPosition(16, 5, 0, 0)
      .setOption('title', "Total hour split in 2020");
   var blob = chartBuilder.build().getBlob();
  destSheet.insertImage(blob, 1, 1);
}
</code>```

Title: Export Google sheet Chart as an image

Body:
Would you please help on how to export a chart to a image using google script.

I wrote this code but it doesn't work. I'm worrying that the API getAs is deprecated.

function TestEmailCharts(){
    var sheet = SpreadsheetApp.getActiveSheet();

  var charts = sheet.getCharts();

  if(charts.length!=0)
  {
  var chartBlobs=new Array(charts.length);
  var emailBody="Charts
";
  var emailImages={};
  for(var i=0;i<charts.length;i++){
    chartBlobs[i]= charts[i].getAs("image/jpeg").setName("chartBlob"+i);
    emailBody= emailBody + "
";
    emailImages["chart"+i]= chartBlobs[i];
  }

  MailApp.sendEmail({
    to: "email@gmail.com",
    subject: "test2",
    htmlBody: emailBody,
    inlineImages:emailImages});
  }
}

To reproduce the problem,  create a Google spread sheet
Create a simple chart with some data.

Add this code to scripts.
Replace email@gmail.com with your email

Normally you should receive an email with chart image
But the problem is that you will receive a email with black image.

Best regards.

Body:
Exporting a Google sheet chart as an image

By Email:
First create the chart and then get its blob. Then send the blob as attachment.

function createPieChart(){
  var sheet = SpreadsheetApp.openById("<ID>").getSheetByName("<SheetName>");
  var chartBuilder = sheet.newChart()
      .asPieChart()
      .set3D()
      .addRange(sheet.getRange("A20").getDataRegion())
      .setPosition(16, 5, 0, 0)
      .setOption('title', "Total hour split in 2020");
  var blob = chartBuilder.build().getBlob();
  sendMail(blob);
}

function sendMail(img){
  MailApp.sendEmail({
    to: "john@domain.com",
    subject: "test",
    htmlBody: "fair enough",
    attachments: [img]}); //If this gives you problems, replace img with img.getAs(MimeType.JPEG)
}

To another spreadsheet (different from where the source data for the chart is):

Similar way, create the chart and then insert the blob as an image in the destination sheet:

function createPieChart(){
  var srcSheet = SpreadsheetApp.openById("<ID>").getSheetByName("<SheetName>");
  var destSheet = SpreadsheetApp.openById("<ID>").getSheetByName("<SheetName>");
   var chartBuilder = srcSheet.newChart()
      .asPieChart()
      .set3D()
      .addRange(sheet.getRange("A20").getDataRegion())
      .setPosition(16, 5, 0, 0)
      .setOption('title', "Total hour split in 2020");
   var blob = chartBuilder.build().getBlob();
  destSheet.insertImage(blob, 1, 1);
}


问:
How can I sign out of the GitKraken client?
I'm using a public computer and I can't figure out how I can sign out my account in the desktop client for Ubuntu. I can't find a logout button. My GitKraken account is connected to GitHub, and I need a way to sign out.</p>

答:
It's conveniently the one of the few options that's hidden in the File menu for some reason.

 Sign into Different Account">


问:
How to query to capture recency and scale in one query?
I've built a query that calculates the number of ids from a table, per url_count.

```<code>with cte as (
  select id, count(distinct.url) url_count
  from table
  group by id
)

select sum(if(url_count >= 1,1,0) scale
from cte
union all
select sum(if(url_count >= 2,1,0) scale
from cte
union all
select sum(if(url_count >= 3,1,0) scale
from cte
union all
select sum(if(url_count >= 4,1,0) scale
from cte
union all
select sum(if(url_count >= 5,1,0) scale
from cte
</code>```

The query above says; "Give me the list of ids and the number of urls they each go to, then accumulate the number of ids who have gone to [1-5] or more urls"

It's ofc a tedious method, but works and outputs something like;

```<code>---------
| scale |
---------
|1213432|
|867554 |
|523523 |
|342232 |
|145889 |
---------
</code>```

From this table, I also have a date field on the last 5 days which I'm working on adding into this query. Thus lies the challenge; Trying to add a second layer of information to the query; i.e. Recency. Been working on multiple approaches to building a query that outputs all the combinations of different scales, per the date.

The sort of output I've imagined is a pivot table which presents something like;

```<code>-------------------------------------------------------------
|   date   | url_co1 | url_co2 | url_co3 | url_co4 | url_co5|
-------------------------------------------------------------
|2020-01-05| 1213432 | 1112321 | 984332  | 632131  | 234124 |
|2020-01-04| 1012131 |  934242 | 867554  | 533242  | 134234 |
|    ...   |   ...   |   ...   |   ...   |   ...   |   ...  |
|    ...   |   ...   |   ...   |   ...   |   ...   |   ...  |
|    ...   |   ...   |   ...   |   ...   |   ...   |   ...  |
-------------------------------------------------------------
</code>```

Where url_co[1-5] represents the number of ids that visited [1-5] or more urls and dates gives up the date that volume was captured. No idea how to write that because once I query:

```<code>with cte as (
  select id, date, count(distinct.url) url_count
  from table
  group by id, date
)
</code>```

I've aggregated to per id, per date, which therefore something goes wrong. =/

Hope that all made sense!

Please, please help! I would appreciate some guidance.

There must be a methodology for getting the combination of volumes per recency that I've missed!

答:
I don't really follow the full question, but the first query can be simplified to:</p>

```<code>select url_count, count(*) as this_count,
       sum(url_count) over (order by url_count desc) as descending_count
from (select id, count(distinct url) as url_count
      from table
      group by id
     ) t
group by url_count
order by url_count;
</code>```

Body:
I've built a query that calculates the number of ids from a table, per url_count.

with cte as (
  select id, count(distinct.url) url_count
  from table
  group by id
)

select sum(if(url_count >= 1,1,0) scale
from cte
union all
select sum(if(url_count >= 2,1,0) scale
from cte
union all
select sum(if(url_count >= 3,1,0) scale
from cte
union all
select sum(if(url_count >= 4,1,0) scale
from cte
union all
select sum(if(url_count >= 5,1,0) scale
from cte

The query above says; "Give me the list of ids and the number of urls they each go to, then accumulate the number of ids who have gone to [1-5] or more urls"

It's ofc a tedious method, but works and outputs something like;

---------
| scale |
---------
|1213432|
|867554 |
|523523 |
|342232 |
|145889 |
---------

From this table, I also have a date field on the last 5 days which I'm working on adding into this query. Thus lies the challenge; Trying to add a second layer of information to the query; i.e. Recency. Been working on multiple approaches to building a query that outputs all the combinations of different scales, per the date.

The sort of output I've imagined is a pivot table which presents something like;

-------------------------------------------------------------
|   date   | url_co1 | url_co2 | url_co3 | url_co4 | url_co5|
-------------------------------------------------------------
|2020-01-05| 1213432 | 1112321 | 984332  | 632131  | 234124 |
|2020-01-04| 1012131 |  934242 | 867554  | 533242  | 134234 |
|    ...   |   ...   |   ...   |   ...   |   ...   |   ...  |
|    ...   |   ...   |   ...   |   ...   |   ...   |   ...  |
|    ...   |   ...   |   ...   |   ...   |   ...   |   ...  |
-------------------------------------------------------------

Where url_co[1-5] represents the number of ids that visited [1-5] or more urls and dates gives up the date that volume was captured. No idea how to write that because once I query:

with cte as (
  select id, date, count(distinct.url) url_count
  from table
  group by id, date
)

I've aggregated to per id, per date, which therefore something goes wrong. =/

Hope that all made sense!

Please, please help! I would appreciate some guidance.

There must be a methodology for getting the combination of volumes per recency that I've missed!

Body:
I don't really follow the full question, but the first query can be simplified to:

select url_count, count(*) as this_count,
       sum(url_count) over (order by url_count desc) as descending_count
from (select id, count(distinct url) as url_count
      from table
      group by id
     ) t
group by url_count
order by url_count;


问:
fork() failing with Out of memory error
The parent process fails with errno=12(Out of memory) when it tries to fork a child. The parent process runs on Linux 3.0 kernel - SLES 11. At the point of forking the child, the parent process has already used up around 70% of the RAM(180GB/256GB). Is there any workaround for this problem?

The application is written in C++, compiled with g++ 4.6.3.

答:
A nicer solution on Linux would be to use vfork or posix_spawn (as it will try to use vfork if possible): vfork "creates new processes without copying the page tables of the parent process", so it will work even if your application uses more than 50% of RAM available.

Note that std::system and QProcess::execute also use fork under the hood, there is even a ticket about this problem in Qt framework: https://bugreports.qt.io/browse/QTBUG-17331

Title: fork() failing with Out of memory error


问:
Creating new columns based on certain strings appearing in a variable atleast twice
I have a data frame containing the variables 'id' and 'var1' similar to the following:

```<code>set.seed(100)
id <- sample(1:3, 10, replace = TRUE)
set.seed(101)
var1 <- sample(LETTERS[1:3], 10, replace = TRUE)
df <- data.frame(id, var1)
</code>```

I want to group the data frame by 'id' and create new columns 'condition1', 'condition2', 'condition3' and so on, if certain strings appear in var1 at least twice. So, when 'df' is grouped by 'id', 'condition1' will be 1 if var1 == 'A' and appears in at least 2 rows or else 'condition1' will be set to 0. Similarly, 'condition2' will be based on 'B' and 'condition3' will be based on 'C'.

So, far I have tried to use dplyr and come up with the following-

```<code>library(dplyr)
df2 <- df %>%
       group_by(id) %>%
       summarise(condition1 = case_when(**var1 == "A" appears in at least 2 rows** ~ 1, **var1 == "A" appears only once or does not appear at all** ~ 0),
                 condition2 = case_when(**var1 == "B" appears in at least 2 rows** ~ 1, **var1 == "B" appears only once or does not appear at all** ~ 0),
                 condition3 = case_when(**var1 == "C" appears in at least 2 rows** ~ 1, **var1 == "C" appears only once or does not appear at all** ~ 0))
</code>```

How do I correctly define the conditions inside case_when? Any other way to solve this would be welcome as well.

答:
Here is a simple way. Use the fact that logical values FALSE/TRUE are coded internally as 0/1 and sum the results of the comparisons. If the sums are greater than 1, it becomes coded as 1, if not, as 0.

```<code>library(tidyverse)

df %>%
  group_by(id) %>%
  mutate(condition1 = as.integer(sum(var1 == "A") > 1),
         condition2 = as.integer(sum(var1 == "B") > 1),
         condition3 = as.integer(sum(var1 == "C") > 1))
## A tibble: 10 x 5
## Groups:   id [3]
#      id var1  condition1 condition2 condition3
#   <int> <fct>      <int>      <int>      <int>
# 1     2 A              1          1          0
# 2     3 A              0          0          1
# 3     2 B              1          1          0
# 4     3 C              0          0          1
# 5     1 C              0          0          0
# 6     2 A              1          1          0
# 7     2 B              1          1          0
# 8     3 C              0          0          1
# 9     2 A              1          1          0
#10     2 C              1          1          0
</code>```

Edit.

According to the comment by the OP, it's summaries by id that is asked for.

```<code>df %>%
  group_by(id) %>%
  summarise(condition1 = as.integer(sum(var1 == "A") > 1),
            condition2 = as.integer(sum(var1 == "B") > 1),
            condition3 = as.integer(sum(var1 == "C") > 1))
## A tibble: 3 x 4
#     id condition1 condition2 condition3
#  <int>      <int>      <int>      <int>
#1     1          0          0          0
#2     2          1          1          0
#3     3          0          0          1
</code>```

Body:
I have a data frame containing the variables 'id' and 'var1' similar to the following:

set.seed(100)
id <- sample(1:3, 10, replace = TRUE)
set.seed(101)
var1 <- sample(LETTERS[1:3], 10, replace = TRUE)
df <- data.frame(id, var1)

I want to group the data frame by 'id' and create new columns 'condition1', 'condition2', 'condition3' and so on, if certain strings appear in var1 at least twice. So, when 'df' is grouped by 'id', 'condition1' will be 1 if var1 == 'A' and appears in at least 2 rows or else 'condition1' will be set to 0. Similarly, 'condition2' will be based on 'B' and 'condition3' will be based on 'C'.

So, far I have tried to use dplyr and come up with the following-

library(dplyr)
df2 <- df %>%
       group_by(id) %>%
       summarise(condition1 = case_when(**var1 == "A" appears in at least 2 rows** ~ 1, **var1 == "A" appears only once or does not appear at all** ~ 0),
                 condition2 = case_when(**var1 == "B" appears in at least 2 rows** ~ 1, **var1 == "B" appears only once or does not appear at all** ~ 0),
                 condition3 = case_when(**var1 == "C" appears in at least 2 rows** ~ 1, **var1 == "C" appears only once or does not appear at all** ~ 0))

How do I correctly define the conditions inside case_when? Any other way to solve this would be welcome as well.

Body:
Here is a simple way. Use the fact that logical values FALSE/TRUE are coded internally as 0/1 and sum the results of the comparisons. If the sums are greater than 1, it becomes coded as 1, if not, as 0.

library(tidyverse)

df %>%
  group_by(id) %>%
  mutate(condition1 = as.integer(sum(var1 == "A") > 1),
         condition2 = as.integer(sum(var1 == "B") > 1),
         condition3 = as.integer(sum(var1 == "C") > 1))
## A tibble: 10 x 5
## Groups:   id [3]
#      id var1  condition1 condition2 condition3
#   <int> <fct>      <int>      <int>      <int>
# 1     2 A              1          1          0
# 2     3 A              0          0          1
# 3     2 B              1          1          0
# 4     3 C              0          0          1
# 5     1 C              0          0          0
# 6     2 A              1          1          0
# 7     2 B              1          1          0
# 8     3 C              0          0          1
# 9     2 A              1          1          0
#10     2 C              1          1          0

Edit.

According to the comment by the OP, it's summaries by id that is asked for.

df %>%
  group_by(id) %>%
  summarise(condition1 = as.integer(sum(var1 == "A") > 1),
            condition2 = as.integer(sum(var1 == "B") > 1),
            condition3 = as.integer(sum(var1 == "C") > 1))
## A tibble: 3 x 4
#     id condition1 condition2 condition3
#  <int>      <int>      <int>      <int>
#1     1          0          0          0
#2     2          1          1          0
#3     3          0          0          1