问:
I want storybook addon actions to display its standard "log" message AND the actual component event handler to update the UI
I can't seem to figure out how to get my event handling function to do its logic to update the UI AND storybook's addon - actions() to log the output.

The reason I want the UI to update is because we're using cypress.io for testing. We've hacked/stubbed the actions messaging (pretty cool, window.postMessage) to access the action message which allows the use of action("functionName"), instead of wiring up a event handling function in [file].stories.tsx. I'd like to do both for my sanity. To check the action message, its a few clicks. I'd rather just see the item get removed. With that, for testing, I'd like to expect the action message (I'm able to do that). We are using alert() to check if something fired, and I'm not a fan.

If this just seems unnecessary, or counter intuitive/productive, do elaborate.

If it helps... <List /> is just that, but has an action button on each item to remove the item from the list.

Using onRemove={actionHandler} prop, below, in List does just that in the UI, removes the item and Cypress is happy, but need the alert() to track. But cant wire up the action() anywhere and no log in the GUI.

If I REMOVE onRemove={actionHandler} and uncomment // onRemove: action("removeItem"), I get the action log I want, but the Item doesn't remove.

I understand actions are supposed to mimic event handler's, but I'd like it to do that AND fire the actual event... if possible or reasonable.

List.stories.tsx
// storybook addons
import { withKnobs } from "@storybook/addon-knobs";

// deps
import React from "react";
import { action } from "@storybook/addon-actions";

// utils
import { CustomEvent } from "../../hooks";

// components
import { Item } from "./Item"
import { List } from "./ListItems"
import { InputHeader } from "../inputs/InputHeader";

// create test states for target dropdown
export default {
  component: List,
  title: "Lists|With Action",
  decorators: [withKnobs]
};

const listItemsData = {
    values: ['Test Value 1', 'Test Value 2', 'Test Value 3', 'Test Value 4', 'Test Value 5'],
    name: "test list story",
    // onRemove: action("removeItem")
};

export const listWithActionButton = () => {
    const [listItemState, setListItemState] = React.useState(listItemsData)
    const actionHandler = (event: CustomEvent<string[]>) => {
        // action("removeItem")()
        setListItemState(prevState => ({
            ...listItemState,
            values: event.target.value,
        }))
    };

    return (
        <>
        <InputHeader headerText="List with Action Buttons" />

        <List
            {...listItemState}
            onRemove={actionHandler}
            />
        </>
    )
};

List.tsx
export const List = ({name, values, onRemove}) => {
  const removeItem = (index: number) => {
      // this is what I want to fire AS WELL as the action log.
      const top = values.slice(0, index);
      const bottom = values.slice(index + 1);
      const updatedOptions = [...top, ...bottom]

      // Fire a custom event to match what our useForm hook expects
      const event: CustomEvent<string[]> = {
        target: {
          value: updatedOptions,
          name
        },
      };
      return onRemove(event);
    };

    return (
        <ListStyle>
            {
                values.map((item, index) => {
                    return (
                        <Item
                            key={index}
                            value={item}
                            removeItem={removeItem}
                            itemIndex={index}
                        />)
                })
            }
        </ListStyle>
    )
};
```

答:
You can do something like this if you want to fire an action AND execute your function.</p>

```<code>  <Button
    onClick={(e) => {
      action('click')(e);
      removeItem();
    }}
    selected={state}
  >
</code>```

Body:
You can do something like this if you want to fire an action AND execute your function.

  <Button
    onClick={(e) => {
      action('click')(e);
      removeItem();
    }}
    selected={state}
  >


来源: stackexchange

问:
Is there a way to create a separate log file for each user ? (spring boot)
I am working on a spring boot application, i want to create a separate logging file for each user of the application, is this possible ?

For example: user1.log, user2.log, user3.log, ....

Thanks.

答:
Although I agree with Kann's answer that the best approach is to filter after the fact, the answer to your question when using Log4j 2 would be to use the RoutingAppender or the SiftingAppender when using Logback. They both work similarly in that they will create new appenders for each unique item which can cause a problem with file handles. Log4j2's RoutingAppender provides for a PurgePolicy to handle that while Logback provides a timeToLive attribute. Logback uses a Discriminator class to choose how to determine how to match the log event to an Appender while Log4j 2 uses either a pattern that should contain a Lookup (Log4j 2's variable substitution mechanism) or a script to perform the matching.

If you are using java.util.logging you will have to write your own mechanism.

ContentLicense: CC BY-SA 4.0


问:
Cannot connect to local postgresql DB using DBeaver
I'm trying to connect to a postgresql database which is in localhost:5432 but I keep getting the error:
FATAL: Ident authentication failed for user "".

I installed Postgres11 on virtual machine running Centos7. Created a database through command line, with the name business_db.

I've checked and postgresql is running in localhost:5432.

My pg_hba.conf file is like this:

# TYPE  DATABASE        USER            ADDRESS                 METHOD
local   all             all                                     peer
host    all             all             127.0.0.1/32           ident
host    all             all             ::1/128                 ident
local   replication     all                                     peer
host    replication     all             127.0.0.1/32            ident
host    replication     all             ::1/128                 ident
```

<p>The pg_ident.conf file doesn't hold any configurations:</p>

<pre class="lang-none prettyprint-override"><code># Put your actual configuration here
# ----------------------------------

# MAPNAME       SYSTEM-USERNAME         PG-USERNAME
</code>```

The database exists as shown by the command:

I'm logged into the system as "dev" user but., whatever I try while testing connection whit DBeaver, I allways get the error:

I also tried to set User as postgres and use my system password but get the same error. What am I missing?

答:
Change the ident to trust if you don't want to enter a password or to md5 if you want to enter a password.

Then reload the PostgreSQL server.

Body:
I'm trying to connect to a postgresql database which is in localhost:5432 but I keep getting the error:
FATAL: Ident authentication failed for user "".

I installed Postgres11 on virtual machine running Centos7. Created a database through command line, with the name business_db.

I've checked and postgresql is running in localhost:5432.

My pg_hba.conf file is like this:

# TYPE  DATABASE        USER            ADDRESS                 METHOD
local   all             all                                     peer
host    all             all             127.0.0.1/32           ident
host    all             all             ::1/128                 ident
local   replication     all                                     peer
host    replication     all             127.0.0.1/32            ident
host    replication     all             ::1/128                 ident

The pg_ident.conf file doesn't hold any configurations:

# Put your actual configuration here
# ----------------------------------

# MAPNAME       SYSTEM-USERNAME         PG-USERNAME

The database exists as shown by the command:

I'm logged into the system as "dev" user but., whatever I try while testing connection whit DBeaver, I allways get the error:

I also tried to set User as postgres and use my system password but get the same error. What am I missing?


问:
Why do I receive "This value should be of type string" when using a DateTime constraint on Symfony 5?
I have the following entity (only attached the relevant parts):

use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ApiResource(mercure=true)
 * @ORM\Entity(repositoryClass="App\Repository\EventRepository")
 */
class Event {
    /**
     * @ORM\Column(type="datetime")
     * @Assert\DateTime
     * @Assert\NotNull
     */
    private $createdAt;

    public function __construct() {
        $this->createdAt = new \DateTime();
    }

    public function getCreatedAt(): ?\DateTimeInterface {
        return $this->createdAt;
    }

    public function setCreatedAt(\DateTimeInterface $createdAt): self {
        $this->createdAt = $createdAt;
        return $this;
    }
}
```

<p>Its repository:</p>

```class EventRepository extends ServiceEntityRepository {
    public function __construct(ManagerRegistry $registry) {
        parent::__construct($registry, Event::class);
    }
}
```

When creating a POST request to the event endpoint (via Postman or the Swagger UI), it fails with the following exception:

答:
You are using the wrong of assertion.

Date expects a string or an object that can be cast into a string. And a DateTimeInterface is neither.

You should be using a Type constraint.

```<code>/**
 * @Assert\Type("\DateTimeInterface")
 */
 private $createdAt;
</code>```

The ability to use Assert\Date to validate DateTime objects was deprecated on Symfony 4.2, and on Symfony 5.0 it was removed altogether.

Body:
I have the following entity (only attached the relevant parts):

use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ApiResource(mercure=true)
 * @ORM\Entity(repositoryClass="App\Repository\EventRepository")
 */
class Event {
    /**
     * @ORM\Column(type="datetime")
     * @Assert\DateTime
     * @Assert\NotNull
     */
    private $createdAt;

    public function __construct() {
        $this->createdAt = new \DateTime();
    }

    public function getCreatedAt(): ?\DateTimeInterface {
        return $this->createdAt;
    }

    public function setCreatedAt(\DateTimeInterface $createdAt): self {
        $this->createdAt = $createdAt;
        return $this;
    }
}

Its repository:

class EventRepository extends ServiceEntityRepository {
    public function __construct(ManagerRegistry $registry) {
        parent::__construct($registry, Event::class);
    }
}

When creating a POST request to the event endpoint (via Postman or the Swagger UI), it fails with the following exception:

Body:
You are using the wrong of assertion.

Date expects a string or an object that can be cast into a string. And a DateTimeInterface is neither.

You should be using a Type constraint.

/**
 * @Assert\Type("\DateTimeInterface")
 */
 private $createdAt;

The ability to use Assert\Date to validate DateTime objects was deprecated on Symfony 4.2, and on Symfony 5.0 it was removed altogether.


问:
How to create a query that return custom post type by Advanced Custom Field(ACF) Taxonony?
you all!

I have categories of Author

1 - Freelancer

2 - Contract

3 - Half-time

I have categories of Books

1 - Novel

2 - Fiction

I have a custom post type Author. Author has custom fields:

Name: Text

Type: Category

I have a custom post type Book. Book has custom fields:

Title: Text

Author: Taxonomy

Type: Category

Pages: Number

I need a query that return ALL BOOKs with Authors that have Contract ID = 1

And

I need a query that return ALL BOOKs with Type = Fiction

Thanks!!!

答:
You should use meta_query to get the desired results:

I need a query that return ALL BOOKs with Authors that have Contract ID = 1

```<code>$freelance_books = get_posts(array(
    'numberposts'   => -1,
    'post_type'     => 'books',
    'meta_key'      => 'book_contract', // Adjust here with your field name
    'meta_value'    => 1
));
</code>```

I need a query that return ALL BOOKs with Type = Fiction

```<code>$fiction_books = get_posts(array(
    'numberposts'   => -1,
    'post_type'     => 'books',
    'meta_key'      => 'book_type', // Adjust here with your field name
    'meta_value'    => 2
));
</code>```

Body:
You should use meta_query to get the desired results:

I need a query that return ALL BOOKs with Authors that have Contract ID = 1

$freelance_books = get_posts(array(
    'numberposts'   => -1,
    'post_type'     => 'books',
    'meta_key'      => 'book_contract', // Adjust here with your field name
    'meta_value'    => 1
));

I need a query that return ALL BOOKs with Type = Fiction

$fiction_books = get_posts(array(
    'numberposts'   => -1,
    'post_type'     => 'books',
    'meta_key'      => 'book_type', // Adjust here with your field name
    'meta_value'    => 2
));


问:
Understanding space complexity - BFS solution - Painting a boolean matrix
I am trying to understand the space complexity of a BFS solution for the painting a boolean matrix problem in "Elements of Programming Interview". It is similar to Flood fill problem (Problem 733) in Leetcode.

The solution goes like this. I can add the current element that needs the change to the queue. Any adjacent (Top/Bottom/Up/Down) nodes need a change as well. So I add them to the queue (If they satisfy the criteria to be added to the queue. Whenever an element from the queue is processed, its adjacent elements are added. We will do the processing till queue is not empty.

I was thinking the space complexity (worst case) will be O(MN) because all the elements could be in the queue as well. But the book mentions that the worst case space complexity is O(M+N) since there are at most O(M+N) entries at a given distance from a node. I understand that elements are constantly getting removed from the queue as well. Even then it is hard for me to imagine how they arrive at this space complexity. Can someone please help me understand?

答:
The key to this is that BFS visits nodes in order of their distance from the starting node. This is what makes BFS suitable for finding shortest paths in unweighted graphs.

At any point in time, the queue cannot contain two nodes u and v such that distance(start, u) and distance(start, v) differ by more than 1. Suppose for the sake of argument that u's distance from the starting node is 3, and v's distance is 5:

If v occurs before u in the queue, then we visit it before u - a contradiction, because BFS visits nodes at earlier distances before nodes at greater distances.

If u occurs before v in the queue, then when we visit u, we will add u's neighbours to the queue. Those neighbours are at distance 4 from the starting node, but they are now after v in the queue, so v will be visited before them despite having a distance greater than 4 - another contradiction.

So at all times, there is some distance d such that the queue contains only nodes at distance d or distance d + 1, and furthermore all nodes at distance d occur before any nodes at distance d + 1 in the queue. This is a loop invariant of the BFS algorithm.

Suppose you are doing BFS on an M-by-N grid where every node is connected to all of its orthogonal neighbours. Then for any d > 0, the number of nodes at distance d from the start is at most 4*d, so the maximum possible size of the queue is 4*d + 4*(d + 1). Also, the maximum distance between any two nodes is M + N - 1. Therefore, O(M + N) is an asymptotic bound on the size of the queue at any time.

In the case where some nodes from the grid are "missing" (i.e. the wrong colour for the region being flood-filled), the maximum distance is O(MN) rather than O(M + N); so this case is considerably more difficult. The intuition is that if the graph has longer paths then it has less "wide open" space for the paths to branch off in, resulting in a smaller queue. In the extreme case, the graph can be one long path, but in that case the queue's size is O(1).

However, there are some graphs where the 4*d bound is breached and hence the queue can be larger. For example, it is possible to construct graphs in the form below where the graph size is O(2k) but the queue size reaches O(3k), so the space complexity of BFS is Θ((M + N)log2 3) on this family of graphs. So the quoted O(M + N) space complexity does not hold in the worst case, but probably holds in the average case.

This image was made by Heap Overflow (posted in the comments); the start node is in yellow, and the nodes in red will be in the queue simultaneously.


问:
The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() for value of array
I am getting the following error:

The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

For the following code:

```<code>for index, value in enumerate(archList):
  if value > rIntTemp:
    print(index)
</code>```

Any idea how to fix this? the value of archList should not be an array.

答:
Hello I have found the issue. rIntTemp is equal to a function return. The function returns x, y so rIntTemp was the array. </p>

<p>My mistake! </p>

Body:
I am getting the following error:

The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

For the following code:

for index, value in enumerate(archList):
  if value > rIntTemp:
    print(index)

Any idea how to fix this? the value of archList should not be an array.

Body:
Hello I have found the issue. rIntTemp is equal to a function return. The function returns x, y so rIntTemp was the array.

My mistake!


问:
write a shell script to ssh to a remote machine and execute commands
I have two questions:

There are multiple remote linux machines, and I need to write a shell script which will execute the same set of commands in each machine. (Including some sudo operations). How can this be done using shell scripting?

When ssh'ing to the remote machine, how to handle when it prompts for RSA fingerprint authentication.

The remote machines are VMs created on the run and I just have their IPs. So, I cant place a script file beforehand in those machines and execute them from my machine.

答:
There is are multiple ways to execute the commands or script in the multiple remote Linux machines.
One simple & easiest way is via pssh (parallel ssh program)

pssh: is a program for executing ssh in parallel on a number of hosts. It provides features such as sending input to all of the processes, passing a password to ssh, saving the output to files, and timing out.

Example & Usage:

Connect to host1 and host2, and print "hello, world" from each:

```<code> pssh -i -H "host1 host2" echo "hello, world"
</code>```

Run commands via a script on multiple servers:

```<code>pssh -h hosts.txt -P -I<./commands.sh
</code>```

Usage & run a command without checking or saving host keys:

```<code>pssh -h hostname_ip.txt -x '-q -o StrictHostKeyChecking=no -o PreferredAuthentications=publickey -o PubkeyAuthentication=yes' -i  'uptime; hostname -f'
</code>```

If the file hosts.txt has a large number of entries, say 100, then the parallelism option may also be set to 100 to ensure that the commands are run concurrently:

```<code>pssh -i -h hosts.txt -p 100 -t 0 sleep 10000
</code>```

Options:

-I: Read input and sends to each ssh process.

-P: Tells pssh to display output as it arrives.

-h: Reads the host's file.

-H : [user@]host[:port] for single-host.

-i: Display standard output and standard error as each host completes

-x args: Passes  extra SSH command-line arguments

-o option: Can be used to give options in the format used in the configuration file.(/etc/ssh/ssh_config) (~/.ssh/config)

-p parallelism: Use the given number as the maximum number of concurrent connections

-q Quiet mode:  Causes most warning and diagnostic messages to be suppressed.

-t: Make connections time out after the given number of seconds. 0 means pssh will not timeout any connections

When ssh'ing to the remote machine, how to handle when it prompts for
  RSA fingerprint authentication.

Disable the StrictHostKeyChecking to handle the RSA authentication prompt.

-o StrictHostKeyChecking=no

Source: man pssh

ContentLicense: CC BY-SA 3.0

Body:
There is are multiple ways to execute the commands or script in the multiple remote Linux machines.
One simple & easiest way is via pssh (parallel ssh program)

pssh: is a program for executing ssh in parallel on a number of hosts. It provides features such as sending input to all of the processes, passing a password to ssh, saving the output to files, and timing out.

Example & Usage:

Connect to host1 and host2, and print "hello, world" from each:

 pssh -i -H "host1 host2" echo "hello, world"

Run commands via a script on multiple servers:

pssh -h hosts.txt -P -I<./commands.sh

Usage & run a command without checking or saving host keys:

pssh -h hostname_ip.txt -x '-q -o StrictHostKeyChecking=no -o PreferredAuthentications=publickey -o PubkeyAuthentication=yes' -i  'uptime; hostname -f'

If the file hosts.txt has a large number of entries, say 100, then the parallelism option may also be set to 100 to ensure that the commands are run concurrently:

pssh -i -h hosts.txt -p 100 -t 0 sleep 10000

Options:

-I: Read input and sends to each ssh process.

-P: Tells pssh to display output as it arrives.

-h: Reads the host's file.

-H : [user@]host[:port] for single-host.

-i: Display standard output and standard error as each host completes

-x args: Passes  extra SSH command-line arguments

-o option: Can be used to give options in the format used in the configuration file.(/etc/ssh/ssh_config) (~/.ssh/config)

-p parallelism: Use the given number as the maximum number of concurrent connections

-q Quiet mode:  Causes most warning and diagnostic messages to be suppressed.

-t: Make connections time out after the given number of seconds. 0 means pssh will not timeout any connections

When ssh'ing to the remote machine, how to handle when it prompts for
  RSA fingerprint authentication.

Disable the StrictHostKeyChecking to handle the RSA authentication prompt.

-o StrictHostKeyChecking=no

Source: man pssh


问:
TextView: Remove spacing and padding on top and bottom
I have one textview which size is 50 dp. I got this result like the picture below.

I want to remove bottom spaces in my textView ,because its height depend on the text size. And I  want to receive background only into my quotation mark.
Is there any way to remove the unused spaces in my textView?

```<code><TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:gravity="top"
                android:text="“"
                android:fontFamily="@font/arialbd"
                android:background="#ff0"
                android:textColor="#E8E9EF"
                android:includeFontPadding="false"
                android:textSize="50dp" />
</code>```

答:
This solution works on my case. To remove bottom padding. Set the layout_height the same size as your textSize or 1dp or 2dp less.

Set includeFontPadding="false". Set android:lineSpacingExtra="0dp"

Body:
I have one textview which size is 50 dp. I got this result like the picture below.

I want to remove bottom spaces in my textView ,because its height depend on the text size. And I  want to receive background only into my quotation mark.
Is there any way to remove the unused spaces in my textView?

<TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:gravity="top"
                android:text="“"
                android:fontFamily="@font/arialbd"
                android:background="#ff0"
                android:textColor="#E8E9EF"
                android:includeFontPadding="false"
                android:textSize="50dp" />


问:
Merge dataframes based on columns and rbind matches
I have two dataframes as:

df <- data.frame(x=c("a","c"), y=c("111","222"))

df1 <- data.frame(x=c("a","b","b","c"), y=c("111","222","111","222"),z=c('xxx','yyy','ddd','ttt'))
```

<p>I want to merge these two dataframes based on column x, in such a way that the matched rows from df1 should be added as rows to df and now as columns as traditionally the merge function joins dataframes on columns. The resulting dataframe should look like:</p>

<pre class="lang-r prettyprint-override"><code>X  Y   Z
a 111 <NA>
a 111 xxx
c 222 <NA>
c 222 ttt
</code>```

I know it can be done through for loops but I was wondering if it is possible through one/two line of code instead of writing multiple for loops.

答:
A base R option:

```<code># Add missing column to df
df[setdiff(names(df1), names(df))] <- NA
# rbind only rows matching on x
rbind(df, df1[df1$x %in% df$x,])
   x   y    z
1  a 111 <NA>
2  c 222 <NA>
11 a 111  xxx
4  c 222  ttt
</code>```

A dplyr option:

```<code>library(dplyr)
bind_rows(df, filter(df1, x %in% df$x))
  x   y    z
1 a 111 <NA>
2 c 222 <NA>
3 a 111  xxx
4 c 222  ttt
</code>```

A data.table option:

```<code>library(data.table)
setDT(df)
setDT(df1)
rbind(df, df1[x %in% df$x], fill = TRUE)
   x   y    z
1: a 111 <NA>
2: c 222 <NA>
3: a 111  xxx
4: c 222  ttt
</code>```

Body:
I have two dataframes as:

df <- data.frame(x=c("a","c"), y=c("111","222"))

df1 <- data.frame(x=c("a","b","b","c"), y=c("111","222","111","222"),z=c('xxx','yyy','ddd','ttt'))

I want to merge these two dataframes based on column x, in such a way that the matched rows from df1 should be added as rows to df and now as columns as traditionally the merge function joins dataframes on columns. The resulting dataframe should look like:

X  Y   Z
a 111 <NA>
a 111 xxx
c 222 <NA>
c 222 ttt

I know it can be done through for loops but I was wondering if it is possible through one/two line of code instead of writing multiple for loops.

Body:
A base R option:

# Add missing column to df
df[setdiff(names(df1), names(df))] <- NA
# rbind only rows matching on x
rbind(df, df1[df1$x %in% df$x,])
   x   y    z
1  a 111 <NA>
2  c 222 <NA>
11 a 111  xxx
4  c 222  ttt

A dplyr option:

library(dplyr)
bind_rows(df, filter(df1, x %in% df$x))
  x   y    z
1 a 111 <NA>
2 c 222 <NA>
3 a 111  xxx
4 c 222  ttt

A data.table option:

library(data.table)
setDT(df)
setDT(df1)
rbind(df, df1[x %in% df$x], fill = TRUE)
   x   y    z
1: a 111 <NA>
2: c 222 <NA>
3: a 111  xxx
4: c 222  ttt


问:
How do you remove the Angular Material mat-ink-bar?
I am having trouble getting the ink bar to be hidden.  I have tried a multitude of different things, but with no success.  Here is the CSS I currently have, which does change the color of the ink-bar.  I wish to disable and hide it completely to remove the border shadow.

```<code>/* active tab ink bar */
::ng-deep .mat-ink-bar {
  background-color: var(--primary-color,$orange) !important;
  display: none !important;
  visibility: hidden !important;
  transition: none !important;
  height: 0px !important;
  width: 0px !important;
}
</code>```

答:
Are you sure it's not the mat-tab-nav-bar :

```<code>::ng-deep .mat-tab-header, .mat-tab-nav-bar {
    border-bottom: 0;
}
</code>```

You can check also this.

Body:
I am having trouble getting the ink bar to be hidden.  I have tried a multitude of different things, but with no success.  Here is the CSS I currently have, which does change the color of the ink-bar.  I wish to disable and hide it completely to remove the border shadow.

/* active tab ink bar */
::ng-deep .mat-ink-bar {
  background-color: var(--primary-color,$orange) !important;
  display: none !important;
  visibility: hidden !important;
  transition: none !important;
  height: 0px !important;
  width: 0px !important;
}

Body:
Are you sure it's not the mat-tab-nav-bar :

::ng-deep .mat-tab-header, .mat-tab-nav-bar {
    border-bottom: 0;
}

You can check also this.


问:
How to init the pyproject.toml file
I found that python can use pyproject.toml to list dependencies instead of requirements.txt file. It's more convenient and is very similar to package.json for node.However, I could not find a documentation to init the pyproject.toml file much like the  npm init command. How to autogenerate the file with virtualenv or pip?
also, is there a way to autoupdate the toml file, as the packagaes get installed, much like npm --save tag, that saves the package to the package.json as its installed?

答: Look at poetry. It can do it for you nicely. Actually I think its the only project that handles this already that I know of.</p>

Title: How to init the pyproject.toml file


问:
How to force a link to use specific route (MVC routing)
I have these two routes:

```<code>routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
        );

        routes.MapRoute(
            "Default2", // Route name
            "{controller}/{action}/{OrderId}/{CustomerID}", // URL with parameters
            new { controller = "NorthwindOrders", action = "Index", OrderId = UrlParameter.Optional, CustomerID = UrlParameter.Optional } // Parameter defaults
        );
</code>```

and want to create link that uses the second route.

How can I do this?

答: Order is very important w/ MapRoutes.  Try reversing the order of those two statements.</p>

Body:
I have these two routes:

routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
        );

        routes.MapRoute(
            "Default2", // Route name
            "{controller}/{action}/{OrderId}/{CustomerID}", // URL with parameters
            new { controller = "NorthwindOrders", action = "Index", OrderId = UrlParameter.Optional, CustomerID = UrlParameter.Optional } // Parameter defaults
        );

and want to create link that uses the second route.

How can I do this?


问:
Detected resolved migration not applied to database on flyway
We are using flyway to manage database schema version and we are facing a problem. Since we work as a team and use git as our source code management, there would be some cases that different people update database schema on their own local repo. If that happens, we will get

Detected resolved migration not applied to database: 2016.03.17.16.46"

The time "2016.03.17.16.46" was added by another person and I have already applied some timestamp later than that time. If that happens, we have to clean all database tables and create them again. We have tried to set false on validateOnMigrate and did flywayClean, but nothing help. Is there another way to change that?

答:
You can also put it in your application.properties file if you want to apply the migrations when starting up the app:

```<code>spring.flyway.out-of-order=true
</code>```

Body:
You can also put it in your application.properties file if you want to apply the migrations when starting up the app:

spring.flyway.out-of-order=true


问:
Trying to implement Drag and Drop gmail attachment from chrome
I have been trying to implement drag and drop a gmail attachment from chrome into my application.

Its possible to drag the file from the email to the desktop and it create the attachment there so I know this must be possible.

I have been able to get it to read the file name, but when I read FileContents from the data object I get an internet shortcut with a link to the file.

Has anyone got this working before? the code at the moment is hard coded for a .txt file

My main DataObjectWrapper class is as follows:

there are too many characters to post all of it but the main method is:

```<code>public object GetDataNative(string format, bool autoConvert)
{
    switch (format)
    {
        case CFSTR_FILEDESCRIPTOR_A:

            IntPtr fileGroupDescriptorAPointer = IntPtr.Zero;
            try
            {
                //use the underlying IDataObject to get the FileGroupDescriptor as a MemoryStream
                MemoryStream fileGroupDescriptorStream = (MemoryStream)this.underlyingDataObject.GetData(CFSTR_FILEDESCRIPTOR_A, autoConvert);
                byte[] fileGroupDescriptorBytes = new byte[fileGroupDescriptorStream.Length];
                fileGroupDescriptorStream.Read(fileGroupDescriptorBytes, 0, fileGroupDescriptorBytes.Length);
                fileGroupDescriptorStream.Close();

                //copy the file group descriptor into unmanaged memory
                fileGroupDescriptorAPointer = Marshal.AllocHGlobal(fileGroupDescriptorBytes.Length);
                Marshal.Copy(fileGroupDescriptorBytes, 0, fileGroupDescriptorAPointer, fileGroupDescriptorBytes.Length);

                //marshal the unmanaged memory to to FILEGROUPDESCRIPTORA struct
                object fileGroupDescriptorObject = Marshal.PtrToStructure(fileGroupDescriptorAPointer, typeof(NativeMethods.FILEGROUPDESCRIPTORA));
                NativeMethods.FILEGROUPDESCRIPTORA fileGroupDescriptor = (NativeMethods.FILEGROUPDESCRIPTORA)fileGroupDescriptorObject;

                //get the pointer to the first file descriptor
                IntPtr fileDescriptorPointer = (IntPtr)((int)fileGroupDescriptorAPointer + Marshal.SizeOf(fileGroupDescriptor.cItems));

                NativeMethods.FILEDESCRIPTORA[] fileDescriptors = new NativeMethods.FILEDESCRIPTORA[fileGroupDescriptor.cItems];

                //loop for the number of files acording to the file group descriptor
                for (int fileDescriptorIndex = 0; fileDescriptorIndex < fileGroupDescriptor.cItems; fileDescriptorIndex++)
                {

                    //marshal the pointer top the file descriptor as a FILEDESCRIPTORA struct and get the file name
                    NativeMethods.FILEDESCRIPTORA fileDescriptor = (NativeMethods.FILEDESCRIPTORA)Marshal.PtrToStructure(fileDescriptorPointer, typeof(NativeMethods.FILEDESCRIPTORA));
                    fileDescriptors[fileDescriptorIndex] = fileDescriptor;

                    //move the file descriptor pointer to the next file descriptor
                    fileDescriptorPointer = (IntPtr)((int)fileDescriptorPointer + Marshal.SizeOf(fileDescriptor));
                }

                fileGroupDescriptor.fgd = fileDescriptors;

                //return the array of filenames
                return fileGroupDescriptor;
            }
            finally
            {
                //free unmanaged memory pointer
                Marshal.FreeHGlobal(fileGroupDescriptorAPointer);
            }

        case CFSTR_FILEDESCRIPTOR_W:

            IntPtr fileGroupDescriptorWPointer = IntPtr.Zero;
            try
            {
                //use the underlying IDataObject to get the FileGroupDescriptorW as a MemoryStream
                MemoryStream fileGroupDescriptorStream = (MemoryStream)this.underlyingDataObject.GetData(CFSTR_FILEDESCRIPTOR_W);
                byte[] fileGroupDescriptorBytes = new byte[fileGroupDescriptorStream.Length];
                fileGroupDescriptorStream.Read(fileGroupDescriptorBytes, 0, fileGroupDescriptorBytes.Length);
                fileGroupDescriptorStream.Close();

                //copy the file group descriptor into unmanaged memory
                fileGroupDescriptorWPointer = Marshal.AllocHGlobal(fileGroupDescriptorBytes.Length);
                Marshal.Copy(fileGroupDescriptorBytes, 0, fileGroupDescriptorWPointer, fileGroupDescriptorBytes.Length);

                //marshal the unmanaged memory to to FILEGROUPDESCRIPTORW struct
                object fileGroupDescriptorObject = Marshal.PtrToStructure(fileGroupDescriptorWPointer, typeof(NativeMethods.FILEGROUPDESCRIPTORW));
                NativeMethods.FILEGROUPDESCRIPTORW fileGroupDescriptor = (NativeMethods.FILEGROUPDESCRIPTORW)fileGroupDescriptorObject;

                //get the pointer to the first file descriptor
                IntPtr fileDescriptorPointer = (IntPtr)((int)fileGroupDescriptorWPointer + Marshal.SizeOf(fileGroupDescriptor.cItems));

                NativeMethods.FILEDESCRIPTORW[] fileDescriptiors = new NativeMethods.FILEDESCRIPTORW[fileGroupDescriptor.cItems];

                //loop for the number of files acording to the file group descriptor
                for (int fileDescriptorIndex = 0; fileDescriptorIndex < fileGroupDescriptor.cItems; fileDescriptorIndex++)
                {
                    //marshal the pointer top the file descriptor as a FILEDESCRIPTORW struct and get the file name
                    NativeMethods.FILEDESCRIPTORW fileDescriptor = (NativeMethods.FILEDESCRIPTORW)Marshal.PtrToStructure(fileDescriptorPointer, typeof(NativeMethods.FILEDESCRIPTORW));
                    fileDescriptiors[fileDescriptorIndex] = fileDescriptor;

                    //move the file descriptor pointer to the next file descriptor
                    fileDescriptorPointer = (IntPtr)((int)fileDescriptorPointer + Marshal.SizeOf(fileDescriptor));
                }

                fileGroupDescriptor.fgd = fileDescriptiors;

                //return the array of filenames
                return fileGroupDescriptor;
            }
            finally
            {
                //free unmanaged memory pointer
                Marshal.FreeHGlobal(fileGroupDescriptorWPointer);
            }

        case CFSTR_FILECONTENTS:

            //override the default handling of FileContents which returns the
            //contents of the first file as a memory stream and instead return
            //a array of MemoryStreams containing the data to each file dropped

            //get the array of filenames which lets us know how many file contents exist
            string[] fileContentNames = (string[])this.GetData(CFSTR_FILEDESCRIPTOR_W);

            //create a MemoryStream array to store the file contents
            MemoryStream[] fileContents = new MemoryStream[fileContentNames.Length];

            //loop for the number of files acording to the file names
            for (int fileIndex = 0; fileIndex < fileContentNames.Length; fileIndex++)
            {
                //get the data at the file index and store in array
                fileContents[fileIndex] = this.GetData(format, fileIndex);
            }

            //return array of MemoryStreams containing file contents
            return fileContents;

        case CFSTR_INETURL_A:

            //use the underlying IDataObject to get the FileGroupDescriptorW as a MemoryStream
            MemoryStream UniformResourceLocatorStream = (MemoryStream)this.underlyingDataObject.GetData(CFSTR_INETURL_A);
            byte[] UniformResourceLocatorBytes = new byte[UniformResourceLocatorStream.Length];
            UniformResourceLocatorStream.Read(UniformResourceLocatorBytes, 0, UniformResourceLocatorBytes.Length);
            UniformResourceLocatorStream.Close();

            string url = null;

            if (UniformResourceLocatorBytes[1] == 0)
                url = Encoding.Unicode.GetString(UniformResourceLocatorBytes);
            else
                url = Encoding.ASCII.GetString(UniformResourceLocatorBytes);

            return url;

        case CFSTR_INETURL_W:

            //use the underlying IDataObject to get the FileGroupDescriptorW as a MemoryStream
            MemoryStream UniformResourceLocatorWStream = (MemoryStream)this.underlyingDataObject.GetData(CFSTR_INETURL_W);
            byte[] UniformResourceLocatorWBytes = new byte[UniformResourceLocatorWStream.Length];
            UniformResourceLocatorWStream.Read(UniformResourceLocatorWBytes, 0, UniformResourceLocatorWBytes.Length);
            UniformResourceLocatorWStream.Close();

            string urlW = null;

            if (UniformResourceLocatorWBytes[1] == 0)
                urlW = Encoding.Unicode.GetString(UniformResourceLocatorWBytes);
            else
                urlW = Encoding.ASCII.GetString(UniformResourceLocatorWBytes);

            return urlW;

        case TEXT_X_MOZ_URL:

            //use the underlying IDataObject to get the FileGroupDescriptorW as a MemoryStream
            MemoryStream textMozStream = (MemoryStream)this.underlyingDataObject.GetData(TEXT_X_MOZ_URL);
            byte[] textMozBytes = new byte[textMozStream.Length];
            textMozStream.Read(textMozBytes, 0, textMozBytes.Length);
            textMozStream.Close();

            string urlText = null;

            if (textMozBytes[1] == 0)
                urlText = Encoding.Unicode.GetString(textMozBytes);
            else
                urlText = Encoding.ASCII.GetString(textMozBytes);

            return urlText;

        case "text/html":

            //use the underlying IDataObject to get the FileGroupDescriptorW as a MemoryStream
            MemoryStream dataFormatStream = (MemoryStream)this.underlyingDataObject.GetData("text/html");
            byte[] dataFormatBytes = new byte[dataFormatStream.Length];
            dataFormatStream.Read(dataFormatBytes, 0, dataFormatBytes.Length);
            dataFormatStream.Close();

            string formatText = null;

            if (dataFormatBytes[1] == 0)
                formatText = Encoding.Unicode.GetString(dataFormatBytes);
            else
                formatText = Encoding.ASCII.GetString(dataFormatBytes);

            return formatText;
    }

    //use underlying IDataObject to handle getting of data
    return this.underlyingDataObject.GetData(format, autoConvert);
}
</code>```

I can get quite a bit of data out of it, but just not in the same was as if it was dropped on the desktop:

```<code>private void Form1_DragDrop(object sender, DragEventArgs e)
{
    string[] dataFormats = e.Data.GetFormats();

    Dictionary<string, object> dataDictionary = new Dictionary<string, object>();

    foreach (string dataFormat in dataFormats)
    {
        dataDictionary.Add(dataFormat, e.Data.GetData(dataFormat));

        Debug.WriteLine(
            String.Format("Data Format: {0}     Has data: {1}       Data: {2}",
                dataFormat,
                dataDictionary[dataFormat] != null ? "Yes" : "No",
                dataDictionary[dataFormat] != null ? dataDictionary[dataFormat] : string.Empty));
    }

    DataObjectWrapper dataWrapper = new DragDropTest.DataObjectWrapper(e.Data);

    DataObjectWrapper.NativeMethods.FILEGROUPDESCRIPTORW fileGroupDescriptorW = dataWrapper.GetFileGroupDescriptorW();

    string url = dataWrapper.GetUniformResourceLocatorA();
    string urlw = dataWrapper.GetUniformResourceLocatorW();
    string mozUrl = dataWrapper.GetTextMozURL();
    string textHTML = dataWrapper.GetTExtHtml();

    Stream[] streams = dataWrapper.GetFileContents();

    byte[] buffer = new byte[1024];

    int received = 0;

    FileStream fileStream = File.OpenWrite(@"c:\temp\hello.txt");
    using (Stream input = streams[0])
    {
        int size = input.Read(buffer, 0, buffer.Length);
        while (size > 0)
        {
            fileStream.Write(buffer, 0, size);
            received += size;

            size = input.Read(buffer, 0, buffer.Length);
        }
    }

    fileStream.Flush();
    fileStream.Close();

    return;
}
</code>```

I have read and tried the below links already:

http://dlaa.me/blog/post/9913083

Drag and Drop large virtual files with IStream using VirtualFileDataObject

Drag and drop large virtual files from C# to Windows Explorer

https://msdn.microsoft.com/en-us/library/windows/desktop/bb776902(v=vs.85).aspx#CFSTR_FILECONTENTS

https://msdn.microsoft.com/en-us/library/windows/desktop/bb776904(v=vs.85).aspx

https://dlaa.me/blog/post/9923072

Drag and drop virtual files using IStream

https://blogs.msdn.microsoft.com/adamroot/2008/02/19/shell-style-drag-and-drop-in-net-wpf-and-winforms/

Implementing drag-drop from Chrome on my .NET Windows form

https://blogs.msdn.microsoft.com/adamroot/2008/02/19/shell-style-drag-and-drop-in-net-part-3/

https://blogs.msdn.microsoft.com/adamroot/2008/02/19/shell-style-drag-and-drop-in-net-wpf-and-winforms/

https://blogs.msdn.microsoft.com/adamroot/2008/02/19/shell-style-drag-and-drop-in-net-part-2/

https://blogs.msdn.microsoft.com/adamroot/2008/02/02/dragdroplib-cs/

https://www.codeproject.com/reference/1091137/windows-clipboard-formats

http://dlaa.me/blog/post/9923072

Drag and drop virtual files using IStream

http://www.ookii.org/Blog/opening_files_via_idroptarget_in_net

https://www.codeproject.com/Articles/28209/Outlook-Drag-and-Drop-in-C

答:
You should be able to drag & drop embedded images with your code. But attachments like zip or pdf files are transfered as "FileDrop" format from Chrome. Unfortunately it uses the asynchronous drag & drop interface which is not natively supported by DotNet. That's why GetData("FileDrop") will always return null.

You need to use the interface IDataObjectAsyncCapability to trigger the download. But first it is necessary to pick apart the DataObject to get to the underlying COM-DataObject:

```<code>using System;
using System.Collections.Specialized;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Threading.Tasks;

namespace Dummy
{
    public class FileDrop
    {
        [ComImport]
        [Guid("3D8B0590-F691-11d2-8EA9-006097DF5BD4")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        public interface IDataObjectAsyncCapability
        {
            void SetAsyncMode([In] Int32 fDoOpAsync);
            void GetAsyncMode([Out] out Int32 pfIsOpAsync);
            void StartOperation([In] IBindCtx pbcReserved);
            void InOperation([Out] out Int32 pfInAsyncOp);
            void EndOperation([In] Int32 hResult, [In] IBindCtx pbcReserved, [In] UInt32 dwEffects);
        }

        public static async Task<StringCollection> GetFileDrop(System.Windows.Forms.DataObject dataobject)
        {
            if (dataobject.ContainsFileDropList())
            {
                var files = dataobject.GetFileDropList();
                if (files.Count == 0)
                {
                    // try async version
                    if (await ProcessFileDropAsync(dataobject))
                    {
                        files = dataobject.GetFileDropList();
                    }
                }

                return files;
            }

            // return empty collection
            return new StringCollection();
        }

        private static async Task<bool> ProcessFileDropAsync(System.Windows.Forms.DataObject dataobject)
        {
            // get the internal ole dataobject
            FieldInfo innerDataField = dataobject.GetType().GetField("innerData", BindingFlags.NonPublic | BindingFlags.Instance);
            var oledataobject = (System.Windows.Forms.IDataObject)innerDataField.GetValue(dataobject);

            var type = oledataobject.GetType();
            if (type.Name == "OleConverter")
            {
                // get the COM-object from the OleConverter
                FieldInfo innerDataField2 = type.GetField("innerData", BindingFlags.NonPublic | BindingFlags.Instance);
                var item = innerDataField2.GetValue(oledataobject);

                var asyncitem = item as IDataObjectAsyncCapability;

                if (asyncitem != null)
                {
                    var isasync = 0;
                    asyncitem.GetAsyncMode(out isasync);
                    if (isasync != 0)
                    {
                        var task = Task.Run(() =>
                        {
                            asyncitem.StartOperation(null);

                            // calling GetData after StartOperation will trigger the download in Chrome
                            // subsequent calls to GetData return cached data
                            // files are downloaded to something like c:\temp\chrome_drag1234_123456789\yourfilename.here
                            var result = dataobject.GetData("FileDrop");

                            asyncitem.EndOperation(0, null, 1); // DROPEFFECT_COPY = 1
                        });

                        await task;

                        return true;
                    }
                }
            }

            return false;
        }
    }
}
</code>```

Call it from your drop handler and files should contain the path to your attachment:

```<code>    private async void panel_DragDrop(object sender, DragEventArgs e)
    {
        var files = await FileDrop.GetFileDrop(e.Data as System.Windows.Forms.DataObject);

        foreach (var file in files)
        {
            Console.WriteLine(file);
        }
    }
</code>```

Body:
I have been trying to implement drag and drop a gmail attachment from chrome into my application.

Its possible to drag the file from the email to the desktop and it create the attachment there so I know this must be possible.

I have been able to get it to read the file name, but when I read FileContents from the data object I get an internet shortcut with a link to the file.

Has anyone got this working before? the code at the moment is hard coded for a .txt file

My main DataObjectWrapper class is as follows:

there are too many characters to post all of it but the main method is:

public object GetDataNative(string format, bool autoConvert)
{
    switch (format)
    {
        case CFSTR_FILEDESCRIPTOR_A:

            IntPtr fileGroupDescriptorAPointer = IntPtr.Zero;
            try
            {
                //use the underlying IDataObject to get the FileGroupDescriptor as a MemoryStream
                MemoryStream fileGroupDescriptorStream = (MemoryStream)this.underlyingDataObject.GetData(CFSTR_FILEDESCRIPTOR_A, autoConvert);
                byte[] fileGroupDescriptorBytes = new byte[fileGroupDescriptorStream.Length];
                fileGroupDescriptorStream.Read(fileGroupDescriptorBytes, 0, fileGroupDescriptorBytes.Length);
                fileGroupDescriptorStream.Close();

                //copy the file group descriptor into unmanaged memory
                fileGroupDescriptorAPointer = Marshal.AllocHGlobal(fileGroupDescriptorBytes.Length);
                Marshal.Copy(fileGroupDescriptorBytes, 0, fileGroupDescriptorAPointer, fileGroupDescriptorBytes.Length);

                //marshal the unmanaged memory to to FILEGROUPDESCRIPTORA struct
                object fileGroupDescriptorObject = Marshal.PtrToStructure(fileGroupDescriptorAPointer, typeof(NativeMethods.FILEGROUPDESCRIPTORA));
                NativeMethods.FILEGROUPDESCRIPTORA fileGroupDescriptor = (NativeMethods.FILEGROUPDESCRIPTORA)fileGroupDescriptorObject;

                //get the pointer to the first file descriptor
                IntPtr fileDescriptorPointer = (IntPtr)((int)fileGroupDescriptorAPointer + Marshal.SizeOf(fileGroupDescriptor.cItems));

                NativeMethods.FILEDESCRIPTORA[] fileDescriptors = new NativeMethods.FILEDESCRIPTORA[fileGroupDescriptor.cItems];

                //loop for the number of files acording to the file group descriptor
                for (int fileDescriptorIndex = 0; fileDescriptorIndex < fileGroupDescriptor.cItems; fileDescriptorIndex++)
                {

                    //marshal the pointer top the file descriptor as a FILEDESCRIPTORA struct and get the file name
                    NativeMethods.FILEDESCRIPTORA fileDescriptor = (NativeMethods.FILEDESCRIPTORA)Marshal.PtrToStructure(fileDescriptorPointer, typeof(NativeMethods.FILEDESCRIPTORA));
                    fileDescriptors[fileDescriptorIndex] = fileDescriptor;

                    //move the file descriptor pointer to the next file descriptor
                    fileDescriptorPointer = (IntPtr)((int)fileDescriptorPointer + Marshal.SizeOf(fileDescriptor));
                }

                fileGroupDescriptor.fgd = fileDescriptors;

                //return the array of filenames
                return fileGroupDescriptor;
            }
            finally
            {
                //free unmanaged memory pointer
                Marshal.FreeHGlobal(fileGroupDescriptorAPointer);
            }

        case CFSTR_FILEDESCRIPTOR_W:

            IntPtr fileGroupDescriptorWPointer = IntPtr.Zero;
            try
            {
                //use the underlying IDataObject to get the FileGroupDescriptorW as a MemoryStream
                MemoryStream fileGroupDescriptorStream = (MemoryStream)this.underlyingDataObject.GetData(CFSTR_FILEDESCRIPTOR_W);
                byte[] fileGroupDescriptorBytes = new byte[fileGroupDescriptorStream.Length];
                fileGroupDescriptorStream.Read(fileGroupDescriptorBytes, 0, fileGroupDescriptorBytes.Length);
                fileGroupDescriptorStream.Close();

                //copy the file group descriptor into unmanaged memory
                fileGroupDescriptorWPointer = Marshal.AllocHGlobal(fileGroupDescriptorBytes.Length);
                Marshal.Copy(fileGroupDescriptorBytes, 0, fileGroupDescriptorWPointer, fileGroupDescriptorBytes.Length);

                //marshal the unmanaged memory to to FILEGROUPDESCRIPTORW struct
                object fileGroupDescriptorObject = Marshal.PtrToStructure(fileGroupDescriptorWPointer, typeof(NativeMethods.FILEGROUPDESCRIPTORW));
                NativeMethods.FILEGROUPDESCRIPTORW fileGroupDescriptor = (NativeMethods.FILEGROUPDESCRIPTORW)fileGroupDescriptorObject;

                //get the pointer to the first file descriptor
                IntPtr fileDescriptorPointer = (IntPtr)((int)fileGroupDescriptorWPointer + Marshal.SizeOf(fileGroupDescriptor.cItems));

                NativeMethods.FILEDESCRIPTORW[] fileDescriptiors = new NativeMethods.FILEDESCRIPTORW[fileGroupDescriptor.cItems];

                //loop for the number of files acording to the file group descriptor
                for (int fileDescriptorIndex = 0; fileDescriptorIndex < fileGroupDescriptor.cItems; fileDescriptorIndex++)
                {
                    //marshal the pointer top the file descriptor as a FILEDESCRIPTORW struct and get the file name
                    NativeMethods.FILEDESCRIPTORW fileDescriptor = (NativeMethods.FILEDESCRIPTORW)Marshal.PtrToStructure(fileDescriptorPointer, typeof(NativeMethods.FILEDESCRIPTORW));
                    fileDescriptiors[fileDescriptorIndex] = fileDescriptor;

                    //move the file descriptor pointer to the next file descriptor
                    fileDescriptorPointer = (IntPtr)((int)fileDescriptorPointer + Marshal.SizeOf(fileDescriptor));
                }

                fileGroupDescriptor.fgd = fileDescriptiors;

                //return the array of filenames
                return fileGroupDescriptor;
            }
            finally
            {
                //free unmanaged memory pointer
                Marshal.FreeHGlobal(fileGroupDescriptorWPointer);
            }

        case CFSTR_FILECONTENTS:

            //override the default handling of FileContents which returns the
            //contents of the first file as a memory stream and instead return
            //a array of MemoryStreams containing the data to each file dropped

            //get the array of filenames which lets us know how many file contents exist
            string[] fileContentNames = (string[])this.GetData(CFSTR_FILEDESCRIPTOR_W);

            //create a MemoryStream array to store the file contents
            MemoryStream[] fileContents = new MemoryStream[fileContentNames.Length];

            //loop for the number of files acording to the file names
            for (int fileIndex = 0; fileIndex < fileContentNames.Length; fileIndex++)
            {
                //get the data at the file index and store in array
                fileContents[fileIndex] = this.GetData(format, fileIndex);
            }

            //return array of MemoryStreams containing file contents
            return fileContents;

        case CFSTR_INETURL_A:

            //use the underlying IDataObject to get the FileGroupDescriptorW as a MemoryStream
            MemoryStream UniformResourceLocatorStream = (MemoryStream)this.underlyingDataObject.GetData(CFSTR_INETURL_A);
            byte[] UniformResourceLocatorBytes = new byte[UniformResourceLocatorStream.Length];
            UniformResourceLocatorStream.Read(UniformResourceLocatorBytes, 0, UniformResourceLocatorBytes.Length);
            UniformResourceLocatorStream.Close();

            string url = null;

            if (UniformResourceLocatorBytes[1] == 0)
                url = Encoding.Unicode.GetString(UniformResourceLocatorBytes);
            else
                url = Encoding.ASCII.GetString(UniformResourceLocatorBytes);

            return url;

        case CFSTR_INETURL_W:

            //use the underlying IDataObject to get the FileGroupDescriptorW as a MemoryStream
            MemoryStream UniformResourceLocatorWStream = (MemoryStream)this.underlyingDataObject.GetData(CFSTR_INETURL_W);
            byte[] UniformResourceLocatorWBytes = new byte[UniformResourceLocatorWStream.Length];
            UniformResourceLocatorWStream.Read(UniformResourceLocatorWBytes, 0, UniformResourceLocatorWBytes.Length);
            UniformResourceLocatorWStream.Close();

            string urlW = null;

            if (UniformResourceLocatorWBytes[1] == 0)
                urlW = Encoding.Unicode.GetString(UniformResourceLocatorWBytes);
            else
                urlW = Encoding.ASCII.GetString(UniformResourceLocatorWBytes);

            return urlW;

        case TEXT_X_MOZ_URL:

            //use the underlying IDataObject to get the FileGroupDescriptorW as a MemoryStream
            MemoryStream textMozStream = (MemoryStream)this.underlyingDataObject.GetData(TEXT_X_MOZ_URL);
            byte[] textMozBytes = new byte[textMozStream.Length];
            textMozStream.Read(textMozBytes, 0, textMozBytes.Length);
            textMozStream.Close();

            string urlText = null;

            if (textMozBytes[1] == 0)
                urlText = Encoding.Unicode.GetString(textMozBytes);
            else
                urlText = Encoding.ASCII.GetString(textMozBytes);

            return urlText;

        case "text/html":

            //use the underlying IDataObject to get the FileGroupDescriptorW as a MemoryStream
            MemoryStream dataFormatStream = (MemoryStream)this.underlyingDataObject.GetData("text/html");
            byte[] dataFormatBytes = new byte[dataFormatStream.Length];
            dataFormatStream.Read(dataFormatBytes, 0, dataFormatBytes.Length);
            dataFormatStream.Close();

            string formatText = null;

            if (dataFormatBytes[1] == 0)
                formatText = Encoding.Unicode.GetString(dataFormatBytes);
            else
                formatText = Encoding.ASCII.GetString(dataFormatBytes);

            return formatText;
    }

    //use underlying IDataObject to handle getting of data
    return this.underlyingDataObject.GetData(format, autoConvert);
}

I can get quite a bit of data out of it, but just not in the same was as if it was dropped on the desktop:

private void Form1_DragDrop(object sender, DragEventArgs e)
{
    string[] dataFormats = e.Data.GetFormats();

    Dictionary<string, object> dataDictionary = new Dictionary<string, object>();

    foreach (string dataFormat in dataFormats)
    {
        dataDictionary.Add(dataFormat, e.Data.GetData(dataFormat));

        Debug.WriteLine(
            String.Format("Data Format: {0}     Has data: {1}       Data: {2}",
                dataFormat,
                dataDictionary[dataFormat] != null ? "Yes" : "No",
                dataDictionary[dataFormat] != null ? dataDictionary[dataFormat] : string.Empty));
    }

    DataObjectWrapper dataWrapper = new DragDropTest.DataObjectWrapper(e.Data);

    DataObjectWrapper.NativeMethods.FILEGROUPDESCRIPTORW fileGroupDescriptorW = dataWrapper.GetFileGroupDescriptorW();

    string url = dataWrapper.GetUniformResourceLocatorA();
    string urlw = dataWrapper.GetUniformResourceLocatorW();
    string mozUrl = dataWrapper.GetTextMozURL();
    string textHTML = dataWrapper.GetTExtHtml();

    Stream[] streams = dataWrapper.GetFileContents();

    byte[] buffer = new byte[1024];

    int received = 0;

    FileStream fileStream = File.OpenWrite(@"c:\temp\hello.txt");
    using (Stream input = streams[0])
    {
        int size = input.Read(buffer, 0, buffer.Length);
        while (size > 0)
        {
            fileStream.Write(buffer, 0, size);
            received += size;

            size = input.Read(buffer, 0, buffer.Length);
        }
    }

    fileStream.Flush();
    fileStream.Close();

    return;
}

I have read and tried the below links already:

http://dlaa.me/blog/post/9913083

Drag and Drop large virtual files with IStream using VirtualFileDataObject

Drag and drop large virtual files from C# to Windows Explorer

https://msdn.microsoft.com/en-us/library/windows/desktop/bb776902(v=vs.85).aspx#CFSTR_FILECONTENTS

https://msdn.microsoft.com/en-us/library/windows/desktop/bb776904(v=vs.85).aspx

https://dlaa.me/blog/post/9923072

Drag and drop virtual files using IStream

https://blogs.msdn.microsoft.com/adamroot/2008/02/19/shell-style-drag-and-drop-in-net-wpf-and-winforms/

Implementing drag-drop from Chrome on my .NET Windows form

https://blogs.msdn.microsoft.com/adamroot/2008/02/19/shell-style-drag-and-drop-in-net-part-3/

https://blogs.msdn.microsoft.com/adamroot/2008/02/19/shell-style-drag-and-drop-in-net-wpf-and-winforms/

https://blogs.msdn.microsoft.com/adamroot/2008/02/19/shell-style-drag-and-drop-in-net-part-2/

https://blogs.msdn.microsoft.com/adamroot/2008/02/02/dragdroplib-cs/

https://www.codeproject.com/reference/1091137/windows-clipboard-formats

http://dlaa.me/blog/post/9923072

Drag and drop virtual files using IStream

http://www.ookii.org/Blog/opening_files_via_idroptarget_in_net

https://www.codeproject.com/Articles/28209/Outlook-Drag-and-Drop-in-C

Body:
You should be able to drag & drop embedded images with your code. But attachments like zip or pdf files are transfered as "FileDrop" format from Chrome. Unfortunately it uses the asynchronous drag & drop interface which is not natively supported by DotNet. That's why GetData("FileDrop") will always return null.

You need to use the interface IDataObjectAsyncCapability to trigger the download. But first it is necessary to pick apart the DataObject to get to the underlying COM-DataObject:

using System;
using System.Collections.Specialized;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Threading.Tasks;

namespace Dummy
{
    public class FileDrop
    {
        [ComImport]
        [Guid("3D8B0590-F691-11d2-8EA9-006097DF5BD4")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        public interface IDataObjectAsyncCapability
        {
            void SetAsyncMode([In] Int32 fDoOpAsync);
            void GetAsyncMode([Out] out Int32 pfIsOpAsync);
            void StartOperation([In] IBindCtx pbcReserved);
            void InOperation([Out] out Int32 pfInAsyncOp);
            void EndOperation([In] Int32 hResult, [In] IBindCtx pbcReserved, [In] UInt32 dwEffects);
        }

        public static async Task<StringCollection> GetFileDrop(System.Windows.Forms.DataObject dataobject)
        {
            if (dataobject.ContainsFileDropList())
            {
                var files = dataobject.GetFileDropList();
                if (files.Count == 0)
                {
                    // try async version
                    if (await ProcessFileDropAsync(dataobject))
                    {
                        files = dataobject.GetFileDropList();
                    }
                }

                return files;
            }

            // return empty collection
            return new StringCollection();
        }

        private static async Task<bool> ProcessFileDropAsync(System.Windows.Forms.DataObject dataobject)
        {
            // get the internal ole dataobject
            FieldInfo innerDataField = dataobject.GetType().GetField("innerData", BindingFlags.NonPublic | BindingFlags.Instance);
            var oledataobject = (System.Windows.Forms.IDataObject)innerDataField.GetValue(dataobject);

            var type = oledataobject.GetType();
            if (type.Name == "OleConverter")
            {
                // get the COM-object from the OleConverter
                FieldInfo innerDataField2 = type.GetField("innerData", BindingFlags.NonPublic | BindingFlags.Instance);
                var item = innerDataField2.GetValue(oledataobject);

                var asyncitem = item as IDataObjectAsyncCapability;

                if (asyncitem != null)
                {
                    var isasync = 0;
                    asyncitem.GetAsyncMode(out isasync);
                    if (isasync != 0)
                    {
                        var task = Task.Run(() =>
                        {
                            asyncitem.StartOperation(null);

                            // calling GetData after StartOperation will trigger the download in Chrome
                            // subsequent calls to GetData return cached data
                            // files are downloaded to something like c:\temp\chrome_drag1234_123456789\yourfilename.here
                            var result = dataobject.GetData("FileDrop");

                            asyncitem.EndOperation(0, null, 1); // DROPEFFECT_COPY = 1
                        });

                        await task;

                        return true;
                    }
                }
            }

            return false;
        }
    }
}

Call it from your drop handler and files should contain the path to your attachment:

    private async void panel_DragDrop(object sender, DragEventArgs e)
    {
        var files = await FileDrop.GetFileDrop(e.Data as System.Windows.Forms.DataObject);

        foreach (var file in files)
        {
            Console.WriteLine(file);
        }
    }


问:
How can I choose from files in local storage instead of from a hardcoded file in res/raw?
I'm trying to write an app that will take an XML file and convert it to HTML using XSLT.

The structure of the XML files will always be the same, but the data inside will change.

I have managed to get it to work using an XML file hardcoded in res/raw.

How can I change the app so that I can choose an XML file from the local storage on the device?

Here is my code:

I have a MainActivity with just a single button that kicks off the Activity that is doing the conversion:

MainActivity

package com.example.xml_html_webview;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button btn = (Button)findViewById(R.id.button);

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(MainActivity.this, LoadXSLTinWebview.class));
            }
        });
    }

}```
</div>
</div>
</p>

<p><strong>activity_main.xml</strong></p>

<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-html lang-html prettyprint-override"><code><?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout></code>```

Activity that does the conversion:

package com.example.xml_html_webview;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.print.PrintAttributes;
import android.print.PrintDocumentAdapter;
import android.print.PrintJob;
import android.print.PrintManager;
import android.util.Log;
import android.view.Window;
import android.webkit.WebView;

import com.example.xml_html_webview.R;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;

import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

public class LoadXSLTinWebview extends Activity {

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        getWindow().requestFeature(Window.FEATURE_PROGRESS);

        WebView webview = new WebView(this);
        setContentView(webview);

        //Reading XSLT
        String strXSLT = GetStyleSheet(R.raw.xsltfile);
        //Reading XML
        String strXML = GetStyleSheet(R.raw.xmlfile);
        /*
         * Loading XSLT...
         */
        //Transform ...
        String html=StaticTransform(strXSLT, strXML);

        // HTML button added to transformed XML
        String html_button=
                "<input type=\"button\" value=\"Print\" onClick=\"createWebPrintJob()\" />\n";

        //Loading the above transformed CSLT in to Webview...
        webview.loadData(html + html_button,"text/html",null);

    }

    /*
     * Transform XSLT to HTML string
     */
    public static String StaticTransform(String strXsl, String strXml) {
        String html = "";

        try {

            InputStream ds = null;
            ds = new ByteArrayInputStream(strXml.getBytes("UTF-8"));

            Source xmlSource = new StreamSource(ds);

            InputStream xs = new ByteArrayInputStream(strXsl.getBytes("UTF-8"));
            Source xsltSource = new StreamSource(xs);

            StringWriter writer = new StringWriter();
            Result result = new StreamResult(writer);
            TransformerFactory tFactory = TransformerFactory.newInstance();
            Transformer transformer = tFactory.newTransformer(xsltSource);
            transformer.transform(xmlSource, result);

            html = writer.toString();

            ds.close();
            xs.close();

            xmlSource = null;
            xsltSource = null;

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (TransformerConfigurationException e) {
            e.printStackTrace();
        } catch (TransformerFactoryConfigurationError e) {
            e.printStackTrace();
        } catch (TransformerException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return html;
    }

    /*
     * Read file from res/raw...
     */
    private String GetStyleSheet(int fileId) {
        String strXsl = null;

        InputStream raw = getResources().openRawResource(fileId);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        int size = 0;
        // Read the entire resource into a local byte buffer.
        byte[] buffer = new byte[1024];
        try {
            while ((size = raw.read(buffer, 0, 1024)) >= 0) {
                outputStream.write(buffer, 0, size);
            }
            raw.close();

            strXsl = outputStream.toString();

            Log.v("Log", "xsl ==> " + strXsl);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return strXsl;

    }```

答:
Well I managed to find a solution using FileUtils to convert my file to a string:

File InstanceXmlFile = Collect.getInstance().getFormController().getInstanceFile();

        String strXML = null;
        try {
            strXML = FileUtils.readFileToString(InstanceXmlFile, "utf-8");
        } catch (IOException e) {
            e.printStackTrace();
        }```

Body:
I'm trying to write an app that will take an XML file and convert it to HTML using XSLT.

The structure of the XML files will always be the same, but the data inside will change.

I have managed to get it to work using an XML file hardcoded in res/raw.

How can I change the app so that I can choose an XML file from the local storage on the device?

Here is my code:

I have a MainActivity with just a single button that kicks off the Activity that is doing the conversion:

MainActivity

package com.example.xml_html_webview;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button btn = (Button)findViewById(R.id.button);

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(MainActivity.this, LoadXSLTinWebview.class));
            }
        });
    }

}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

Activity that does the conversion:

package com.example.xml_html_webview;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.print.PrintAttributes;
import android.print.PrintDocumentAdapter;
import android.print.PrintJob;
import android.print.PrintManager;
import android.util.Log;
import android.view.Window;
import android.webkit.WebView;

import com.example.xml_html_webview.R;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;

import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

public class LoadXSLTinWebview extends Activity {

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        getWindow().requestFeature(Window.FEATURE_PROGRESS);

        WebView webview = new WebView(this);
        setContentView(webview);

        //Reading XSLT
        String strXSLT = GetStyleSheet(R.raw.xsltfile);
        //Reading XML
        String strXML = GetStyleSheet(R.raw.xmlfile);
        /*
         * Loading XSLT...
         */
        //Transform ...
        String html=StaticTransform(strXSLT, strXML);

        // HTML button added to transformed XML
        String html_button=
                "<input type=\"button\" value=\"Print\" onClick=\"createWebPrintJob()\" />\n";

        //Loading the above transformed CSLT in to Webview...
        webview.loadData(html + html_button,"text/html",null);

    }

    /*
     * Transform XSLT to HTML string
     */
    public static String StaticTransform(String strXsl, String strXml) {
        String html = "";

        try {

            InputStream ds = null;
            ds = new ByteArrayInputStream(strXml.getBytes("UTF-8"));

            Source xmlSource = new StreamSource(ds);

            InputStream xs = new ByteArrayInputStream(strXsl.getBytes("UTF-8"));
            Source xsltSource = new StreamSource(xs);

            StringWriter writer = new StringWriter();
            Result result = new StreamResult(writer);
            TransformerFactory tFactory = TransformerFactory.newInstance();
            Transformer transformer = tFactory.newTransformer(xsltSource);
            transformer.transform(xmlSource, result);

            html = writer.toString();

            ds.close();
            xs.close();

            xmlSource = null;
            xsltSource = null;

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (TransformerConfigurationException e) {
            e.printStackTrace();
        } catch (TransformerFactoryConfigurationError e) {
            e.printStackTrace();
        } catch (TransformerException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return html;
    }

    /*
     * Read file from res/raw...
     */
    private String GetStyleSheet(int fileId) {
        String strXsl = null;

        InputStream raw = getResources().openRawResource(fileId);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        int size = 0;
        // Read the entire resource into a local byte buffer.
        byte[] buffer = new byte[1024];
        try {
            while ((size = raw.read(buffer, 0, 1024)) >= 0) {
                outputStream.write(buffer, 0, size);
            }
            raw.close();

            strXsl = outputStream.toString();

            Log.v("Log", "xsl ==> " + strXsl);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return strXsl;

    }


答:
value > rIntTemp is producing an array like array([True, False]). I can think of at least six different functions that could reduce this to a single Boolean value:

lambda a: True

lambda a: False

lambda a: a[0]

lambda a: a[1]

lambda a: a[0] and a[1]

lambda a: a[0] or a[1]

(There are more; I didn't bother getting into ones that use not.)

So which one should numpy use? It chooses to use none of them, instead requiring you to be explicit about which condition you want. #5 is a.all(). #6 is a.any().

Title: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() for value of array


问:
NGXS: Testing Asynchronous Actions: Automatic subscription doesn't work
from official website NGXS

I write unit tests for NGXS store(Jasmine + Karma, angular 2)

In NGXS store in Asynchronous Actions(it's like Effect in NGRX) we don't subscribe inside - we just return observable. And it's fine, because the automatics subscription works.

BUT when I launch my tests, the automatic subscription on Asynchronous Actions(EFFECTS) - just doesn't work. As the result - test failed.

To sum up - I can't test Asynchronous Actions NGXS

What I have already  tried :
1) I wrote like in the official website NGXS(in the picture) 2)I tried it(done()) construction, 3) I tried actions$.subscribe() construction.

It works when I make manually - .subscribe() in the Action - but it's problem, because it have to work without this

This is link to official page: https://www.ngxs.io/recipes/unit-testing (topic : Testing Asynchronous Actions)
Please, help :)

答:
THE ANSWER</p>

```<code>`
// it doesn't work for me:
myStubFunction: () => {
    return of(stubResult);
};
// the solution was
myStubFunction: () => {
    return timer(0).pipe(mergMap(()=>of(stubResult)));
};
`
</code>```

Body:
THE ANSWER

`
// it doesn't work for me:
myStubFunction: () => {
    return of(stubResult);
};
// the solution was
myStubFunction: () => {
    return timer(0).pipe(mergMap(()=>of(stubResult)));
};
`


问:
Angular Universal + Firebase Cloud Function causing memory limit exceeded
Currently I'm working on an Angular 8 application which uses Firebase as backend.

I followed Jeff Delaney's Tutorial and suceeded to deploy on a cloud function called ssr my express server.

Everything works fine... almost ! When the ssr function is deployed, I can see an increase of memory usage of all my cloud functions even the smallest (1 transaction with a get and 1 update in the transaction) :

functions/src/index.ts

```<code>// The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
import * as functions from 'firebase-functions';
// The Firebase Admin SDK to access Firestore.
import * as admin from 'firebase-admin';

admin.initializeApp();

export const ssr = functions.https.onRequest(require(`${process.cwd()}/dist/server`).app);

export const unsubscribeToMeal = functions.region('europe-west1').https.onCall((data) => {
  const mealDoc = admin.firestore().doc('meals/' + data.meal.uid);
  const adminDoc = admin.firestore().doc('users/' + data.meal.adminId);
  return admin.firestore().runTransaction(t => {
    return t.get(mealDoc)
      .then(doc => {
        const meal = doc.data();
        if (doc.exists && meal) {
          const promises = [];
          const participantIndex = meal.users.findIndex((element: any) => {
            return element.detail.uid === data.userToUnsubscribe.uid;
          });
          meal.users.splice(participantIndex, 1);
          const pendingRequest = meal.users.filter((user: any) => user.status === 'pending').length > 0;
          const p4 = t.update(mealDoc, { 'users': meal.users, 'participantId': admin.firestore.FieldValue.arrayRemove(data.userToUnsubscribe.uid), 'nbRemainingPlaces': meal['nbRemainingPlaces'] + 1, 'pendingRequest': pendingRequest })
          promises.push(p4);
          if (promises.length > 0) {
            return Promise.all(promises)
              .then(() => console.log('user unsubscribed'))
              .catch((err: any) => console.log('error unsubscribing user : ' + data.userToUnsubscribe.first_name + ' ' + data.userToUnsubscribe.last_name + ' of the meal ' + meal.uid + '. Err : ' + err))
          }
          else {
            // doc.data() will be undefined in this case
            throw new functions.https.HttpsError('not-found', 'no such document!');
          }
        } else {
          // doc.data() will be undefined in this case
          console.log('doc does not exist');
          throw new functions.https.HttpsError('not-found', 'no such document!');
        }
      })
  })
});
</code>```

Triggering unsubscribeToMeal function goes from 60MB memory usage without the ssr function deployed to 240MB memory usage with.

So I am wondering what is happening ? It looks like the express server app is bootstrap on each cloud function instance which causes an increase of memory use and so more billing.

I limited global variables to minimze cold start as Doug Stevenson explains here, so it shouldn't be that.

server.ts

```<code>(global as any).WebSocket = require('ws');
(global as any).XMLHttpRequest = require('xhr2');

import 'zone.js/dist/zone-node';
import 'reflect-metadata';
import { enableProdMode } from '@angular/core';
import * as express from 'express';
import { join } from 'path';

// Faster server renders w/ Prod mode (dev mode never needed)
enableProdMode();

// Express server
export const app = express();
import * as cookieParser from 'cookie-parser';
import { from } from 'rxjs';
app.use(cookieParser());

const PORT = process.env.PORT || 4000;
const DIST_FOLDER = join(process.cwd(), 'dist/browser');

// * NOTE :: leave this as require() since this file is built Dynamically from webpack
const { AppServerModuleNgFactory, LAZY_MODULE_MAP, ngExpressEngine, provideModuleMap } = require('./dist/server/main');

// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
app.engine('html', ngExpressEngine({
  bootstrap: AppServerModuleNgFactory,
  providers: [
    provideModuleMap(LAZY_MODULE_MAP)
  ]
}));

app.set('view engine', 'html');
app.set('views', DIST_FOLDER);

// Example Express Rest API endpoints
// app.get('/api/**', (req, res) => { });
// Serve static files from /browser
app.get('*.*', express.static(DIST_FOLDER, {
  maxAge: '1y'
}));

// All regular routes use the Universal engine
app.get('*', (req: express.Request, res: express.Response) => {
  res.render('index2', {
    req
  });
});

// Start up the Node server
app.listen(PORT, () => {
  console.log(`Node Express server listening on http://localhost:${PORT}`);
});
</code>```

Any solution to still have low memory usage (without increasing memory limit of the function) and at the same time ssr function with express server for angular universal ?

答:
After getting in touch with the firebase community: "using firebase deploy --only functions  will redeploy the code for all your functions and the memory used will be cumulative total of all those functions loaded together".
So the solution is to split functions into different files and use process.env.[functionName] with a if statement as explained here to avoid this increase of memory for the expressFunction.</p>

Body:
Currently I'm working on an Angular 8 application which uses Firebase as backend.

I followed Jeff Delaney's Tutorial and suceeded to deploy on a cloud function called ssr my express server.

Everything works fine... almost ! When the ssr function is deployed, I can see an increase of memory usage of all my cloud functions even the smallest (1 transaction with a get and 1 update in the transaction) :

functions/src/index.ts

// The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
import * as functions from 'firebase-functions';
// The Firebase Admin SDK to access Firestore.
import * as admin from 'firebase-admin';

admin.initializeApp();

export const ssr = functions.https.onRequest(require(`${process.cwd()}/dist/server`).app);

export const unsubscribeToMeal = functions.region('europe-west1').https.onCall((data) => {
  const mealDoc = admin.firestore().doc('meals/' + data.meal.uid);
  const adminDoc = admin.firestore().doc('users/' + data.meal.adminId);
  return admin.firestore().runTransaction(t => {
    return t.get(mealDoc)
      .then(doc => {
        const meal = doc.data();
        if (doc.exists && meal) {
          const promises = [];
          const participantIndex = meal.users.findIndex((element: any) => {
            return element.detail.uid === data.userToUnsubscribe.uid;
          });
          meal.users.splice(participantIndex, 1);
          const pendingRequest = meal.users.filter((user: any) => user.status === 'pending').length > 0;
          const p4 = t.update(mealDoc, { 'users': meal.users, 'participantId': admin.firestore.FieldValue.arrayRemove(data.userToUnsubscribe.uid), 'nbRemainingPlaces': meal['nbRemainingPlaces'] + 1, 'pendingRequest': pendingRequest })
          promises.push(p4);
          if (promises.length > 0) {
            return Promise.all(promises)
              .then(() => console.log('user unsubscribed'))
              .catch((err: any) => console.log('error unsubscribing user : ' + data.userToUnsubscribe.first_name + ' ' + data.userToUnsubscribe.last_name + ' of the meal ' + meal.uid + '. Err : ' + err))
          }
          else {
            // doc.data() will be undefined in this case
            throw new functions.https.HttpsError('not-found', 'no such document!');
          }
        } else {
          // doc.data() will be undefined in this case
          console.log('doc does not exist');
          throw new functions.https.HttpsError('not-found', 'no such document!');
        }
      })
  })
});

Triggering unsubscribeToMeal function goes from 60MB memory usage without the ssr function deployed to 240MB memory usage with.

So I am wondering what is happening ? It looks like the express server app is bootstrap on each cloud function instance which causes an increase of memory use and so more billing.

I limited global variables to minimze cold start as Doug Stevenson explains here, so it shouldn't be that.

server.ts

(global as any).WebSocket = require('ws');
(global as any).XMLHttpRequest = require('xhr2');

import 'zone.js/dist/zone-node';
import 'reflect-metadata';
import { enableProdMode } from '@angular/core';
import * as express from 'express';
import { join } from 'path';

// Faster server renders w/ Prod mode (dev mode never needed)
enableProdMode();

// Express server
export const app = express();
import * as cookieParser from 'cookie-parser';
import { from } from 'rxjs';
app.use(cookieParser());

const PORT = process.env.PORT || 4000;
const DIST_FOLDER = join(process.cwd(), 'dist/browser');

// * NOTE :: leave this as require() since this file is built Dynamically from webpack
const { AppServerModuleNgFactory, LAZY_MODULE_MAP, ngExpressEngine, provideModuleMap } = require('./dist/server/main');

// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
app.engine('html', ngExpressEngine({
  bootstrap: AppServerModuleNgFactory,
  providers: [
    provideModuleMap(LAZY_MODULE_MAP)
  ]
}));

app.set('view engine', 'html');
app.set('views', DIST_FOLDER);

// Example Express Rest API endpoints
// app.get('/api/**', (req, res) => { });
// Serve static files from /browser
app.get('*.*', express.static(DIST_FOLDER, {
  maxAge: '1y'
}));

// All regular routes use the Universal engine
app.get('*', (req: express.Request, res: express.Response) => {
  res.render('index2', {
    req
  });
});

// Start up the Node server
app.listen(PORT, () => {
  console.log(`Node Express server listening on http://localhost:${PORT}`);
});

Any solution to still have low memory usage (without increasing memory limit of the function) and at the same time ssr function with express server for angular universal ?


问:
Making a 2-player web-based textual game
I'm making a simple web-based, turn-based game and am trying to determine what modules exist out there to help me on this task.

Here's the web app I'm looking to build:

User visits the homepage, clicks on a "play game" link

This takes the user to a "game room" where he either joins someone else who has been waiting for a partner to play with or waits for someone to join him

As soon as there are two users in the room, the game starts. It's a very simple turn-based textual game. One user enters a number, then the other user responds by entering another number, and so on, until some conditions are met and the game is over; each player is shown their final score.

My default plan has been to do this using Django and AJAX. Are there any existing modules/frameworks out there that would potentially save me some of the work of writing this from scratch? (Note: I might be able to negotiate to have this done in .NET if there are some great .NET libraries.)

答:
If you're not going to have huge numbers of concurrent users or want it done quickly I would go for holding game state on the server and polling via Ajax.

The js library of your choice will make that polling easier.

If you want it to be larger and hairier, you might look at Strophe, a js library for writing XMPP clients -- it has a handful of example sites.

OwnerDisplayName: RexE

ContentLicense: CC BY-SA 2.5

OwnerDisplayName: wombleton


问:
How to render jsx based on some condition using ternary operation in react?
i want to render the jsx based on a condition using ternary operation in react.

What i am trying to do?

i have the code like below that works perfect.

```<code>return (
    {this.has_rendered() && this.items_loaded()
        ? <ChildComponent/>
        : <ChildComponent
            on_prev={null}/>}
)
</code>```

Now i want to check for other condition if its !current_user then i want to pass another prop named "on_next" to ChildComponent.

```<code>{this.has_rendered() && this.items_loaded() && !current_user &&
    <ChildComponent/>}
{!this.has_rendered() && !this.items_loaded() && !current_user &&
    <ChildComponent on_prev={null}/>}
{this.has_rendered() && this.itemss_loaded() && current_user &&
    <ChildComponent
        on_next={somevalue}/>}
{!this.has_rendered() && !this.items_loaded() && current_user &&
                <NavigationContent
                    on_prev={null}
                    on_next={somevalue}/>}
</code>```

The above code works but as you see there is repetition of code. how can i fix this with ternary operator. could someone help me with this.

thanks.

答:
Nested ternary is a bad idea.
You should use variables in this case</p>

```<code>let component = null;
if (this.has_rendered() && this.items_loaded()) {
  component = current_user? <ChildComponent/> : <ChildComponent on_prev={null}/>
} else {
  component = ...
}
</code>```

Body:
i want to render the jsx based on a condition using ternary operation in react.

What i am trying to do?

i have the code like below that works perfect.

return (
    {this.has_rendered() && this.items_loaded()
        ? <ChildComponent/>
        : <ChildComponent
            on_prev={null}/>}
)

Now i want to check for other condition if its !current_user then i want to pass another prop named "on_next" to ChildComponent.

{this.has_rendered() && this.items_loaded() && !current_user &&
    <ChildComponent/>}
{!this.has_rendered() && !this.items_loaded() && !current_user &&
    <ChildComponent on_prev={null}/>}
{this.has_rendered() && this.itemss_loaded() && current_user &&
    <ChildComponent
        on_next={somevalue}/>}
{!this.has_rendered() && !this.items_loaded() && current_user &&
                <NavigationContent
                    on_prev={null}
                    on_next={somevalue}/>}

The above code works but as you see there is repetition of code. how can i fix this with ternary operator. could someone help me with this.

thanks.

Body:
Nested ternary is a bad idea.
You should use variables in this case

let component = null;
if (this.has_rendered() && this.items_loaded()) {
  component = current_user? <ChildComponent/> : <ChildComponent on_prev={null}/>
} else {
  component = ...
}


问:
First job in second stage contains previous job's state in GitLab
I have run across an issue where the first job in my test stage receives the entire state of my previous build job when I don't expect it too. I've simplified the problem down as much as possible in order to still reproduce the issue. Essentially, build runs and checks out my repo. ls -al prints the working directory out which contains my checked out repo. test-one runs, skips the git checkout, and prints the working directory which contains the git checkout from the previous build job. test-two runs, skips the git checkout, and prints the working directory which contains an empty directory as expected.

My questions are, did I configure my .gitlab-ci.yml file incorrectly, do my expectations lack understanding of how GitLab should work, is GitLab or the runner improperly configured, or is this a bug?

Things to note:

I am using GitLab version: 12.6.4-ee

I am NOT the GitLab administrator

The jobs do not depend on each other and the scripts simply print the current working directory.

My docker image is simply a clean base image of a Linux distro with nothing but common Linux commands installed.

linux-runner is a GitLab-runner running as a service on my Linux server.

I disable git from checking out my repo in the test jobs in order to see that the checkout from the build job is present in test-one.

Below is my .gitlab-ci.yml file simplified:

```<code>image: $DOCKER_REGISTRY/my-image:latest

build:
    stage: build
    tags:
        - linux-runner
    script:
        - ls -al

test-one:
    stage: test
    tags:
        - linux-runner
    variables:
        GIT_STRATEGY: none
    script:
        - ls -al

 test-two:
    stage: test
    tags:
        - linux-runner
    variables:
        GIT_STRATEGY: none
    script:
        - ls -al
</code>```

答: This appears to be caused by my usage of GIT_STRATEGY: none. By removing the variables I began to receive expected behavior once again.</p>

Body:
I have run across an issue where the first job in my test stage receives the entire state of my previous build job when I don't expect it too. I've simplified the problem down as much as possible in order to still reproduce the issue. Essentially, build runs and checks out my repo. ls -al prints the working directory out which contains my checked out repo. test-one runs, skips the git checkout, and prints the working directory which contains the git checkout from the previous build job. test-two runs, skips the git checkout, and prints the working directory which contains an empty directory as expected.

My questions are, did I configure my .gitlab-ci.yml file incorrectly, do my expectations lack understanding of how GitLab should work, is GitLab or the runner improperly configured, or is this a bug?

Things to note:

I am using GitLab version: 12.6.4-ee

I am NOT the GitLab administrator

The jobs do not depend on each other and the scripts simply print the current working directory.

My docker image is simply a clean base image of a Linux distro with nothing but common Linux commands installed.

linux-runner is a GitLab-runner running as a service on my Linux server.

I disable git from checking out my repo in the test jobs in order to see that the checkout from the build job is present in test-one.

Below is my .gitlab-ci.yml file simplified:

image: $DOCKER_REGISTRY/my-image:latest

build:
    stage: build
    tags:
        - linux-runner
    script:
        - ls -al

test-one:
    stage: test
    tags:
        - linux-runner
    variables:
        GIT_STRATEGY: none
    script:
        - ls -al

 test-two:
    stage: test
    tags:
        - linux-runner
    variables:
        GIT_STRATEGY: none
    script:
        - ls -al