问:
How to grab images in JPEG format in higher Fps from IP Camera
Hy Everyone!

I am having a problem in grabbing images from a Panasonic IP Camera in JPEG format infact the problem is with the fps because the fps is always remains 1 or 2 not more than it but infact camera supports upto 30 the cam model is Panasonic WV-SP302E i am using the following C# code to grab the image and display it in my winforms app

```<code>public partial class Form1 : Form
{
    // indicates wether to prevent caching in case of a proxy server or not
    private bool preventCaching = false;

    public Form1()
    {
        InitializeComponent();
    }

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        while (true)
        {
            this.pictureBox1.Image = this.GetSingleFrame(@"http://ipaddress/SnapshotJPEG?Resolution=320x240&Quality=Standard");
        }
    }

    /// <summary>
    /// Get a single JPEG frame from the camera
    /// </summary>
    /// <param name="source">JPEG Stream source</param>
    /// <exception cref="WebException">If the IP camera is not receable or an error is occured</exception>
    /// <exception cref="Exception">If an unknown error occured</exception>
    public Bitmap GetSingleFrame(string source)
    {
        byte[] buffer = new byte[512 * 1024];   // buffer to read stream
        HttpWebRequest req = null;
        WebResponse resp = null;
        Stream stream = null;
        Random rnd = new Random((int)DateTime.Now.Ticks);

        try
        {
            int read, total = 0;

            // create request
            if (!preventCaching)
            {
                req = (HttpWebRequest)WebRequest.Create(source);
            }
            else
            {
                req = (HttpWebRequest)WebRequest.Create(source + ((source.IndexOf('?') == -1) ? '?' : '&') + "fake=" + rnd.Next().ToString());
            }
            // set login and password
            req.Credentials = new NetworkCredential("root", "a");

            req.Timeout = -1;

            resp = req.GetResponse();

            // get response stream
            stream = resp.GetResponseStream();

            // loop
            do
            {
                read = stream.Read(buffer, total, 1024);

                total += read;
            }
            while (read != 0);

            Bitmap bmp = (Bitmap)Bitmap.FromStream(new MemoryStream(buffer, 0, total));

            return bmp;
        }
        catch (WebException ex)
        {
            string s = ex.ToString();
            return null;
        }
        catch (Exception ex)
        {
            string s = ex.ToString();
            return null;
        }
        finally
        {
            // abort request
            if (req != null)
            {
                req.Abort();
                req = null;
            }
            // close response stream
            if (stream != null)
            {
                stream.Close();
                stream = null;
            }
            // close response
            if (resp != null)
            {
                resp.Close();
                resp = null;
            }
        }
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        this.backgroundWorker1.RunWorkerAsync();
    }
}
</code>```

I am even using the backgrounworker component to grab images in another thread but still 2 fps. Any idea how to increase the fps

答:
Looks like you have quite a bit of set up to get that stream going. Taking the allocation out of there so you're not constantly allocating and freeing will help.

Reading multiple frames once you've got the stream going will probably help (i.e. yielding bitmaps from within your data acquisition loop). FYI, you shouldn't be calling GUI operations from a non-gui thread. Use ReportProgress to send the data back.

Are you certain it's the capture that's taking the time as opposed to displaynig it? Have you tried removing the drawing code to test?

Body:
Hy Everyone!

I am having a problem in grabbing images from a Panasonic IP Camera in JPEG format infact the problem is with the fps because the fps is always remains 1 or 2 not more than it but infact camera supports upto 30 the cam model is Panasonic WV-SP302E i am using the following C# code to grab the image and display it in my winforms app

public partial class Form1 : Form
{
    // indicates wether to prevent caching in case of a proxy server or not
    private bool preventCaching = false;

    public Form1()
    {
        InitializeComponent();
    }

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        while (true)
        {
            this.pictureBox1.Image = this.GetSingleFrame(@"http://ipaddress/SnapshotJPEG?Resolution=320x240&Quality=Standard");
        }
    }

    ///
    /// Get a single JPEG frame from the camera
    ///
    /// <param name="source">JPEG Stream source</param>
    /// <exception cref="WebException">If the IP camera is not receable or an error is occured</exception>
    /// <exception cref="Exception">If an unknown error occured</exception>
    public Bitmap GetSingleFrame(string source)
    {
        byte[] buffer = new byte[512 * 1024];   // buffer to read stream
        HttpWebRequest req = null;
        WebResponse resp = null;
        Stream stream = null;
        Random rnd = new Random((int)DateTime.Now.Ticks);

        try
        {
            int read, total = 0;

            // create request
            if (!preventCaching)
            {
                req = (HttpWebRequest)WebRequest.Create(source);
            }
            else
            {
                req = (HttpWebRequest)WebRequest.Create(source + ((source.IndexOf('?') == -1) ? '?' : '&') + "fake=" + rnd.Next().ToString());
            }
            // set login and password
            req.Credentials = new NetworkCredential("root", "a");

            req.Timeout = -1;

            resp = req.GetResponse();

            // get response stream
            stream = resp.GetResponseStream();

            // loop
            do
            {
                read = stream.Read(buffer, total, 1024);

                total += read;
            }
            while (read != 0);

            Bitmap bmp = (Bitmap)Bitmap.FromStream(new MemoryStream(buffer, 0, total));

            return bmp;
        }
        catch (WebException ex)
        {
            string s = ex.ToString();
            return null;
        }
        catch (Exception ex)
        {
            string s = ex.ToString();
            return null;
        }
        finally
        {
            // abort request
            if (req != null)
            {
                req.Abort();
                req = null;
            }
            // close response stream
            if (stream != null)
            {
                stream.Close();
                stream = null;
            }
            // close response
            if (resp != null)
            {
                resp.Close();
                resp = null;
            }
        }
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        this.backgroundWorker1.RunWorkerAsync();
    }
}

I am even using the backgrounworker component to grab images in another thread but still 2 fps. Any idea how to increase the fps


来源: stackexchange

问:
Cucable Plugin not running Scenarios in parallel
I'm trying to run Scenario's in parallel using Trivago's Cucable Plugin. To test it before implementing it my project I download this project.

https://github.com/trivago/cucable-plugin/tree/master/example-project

I tried, mvn clean verify and it created *IT.java files in target folder, but I noticed these are not running in parallel.

How do I know? I added sleep in each statement. Largest sleep is 15 seconds, so the total build should be approx 16 seconds, but it is showing 30 (sum of all sleeps of all scenarios 2+5+15+8) seconds.

cucable.template

```<code>import cucumber.api.CucumberOptions;
import org.junit.runner.RunWith;

@RunWith(Cucumber.class)
@CucumberOptions(
        glue = "steps",
        features = {"target/parallel/features/[CUCABLE:FEATURE].feature"},
        plugin = {"json:target/cucumber-report/[CUCABLE:RUNNER].json"}
)
public class [CUCABLE:RUNNER] {
    // [CUCABLE:CUSTOM:comment]
}
</code>```

pom.xml

```<code><?xml version="1.0" encoding="UTF-8"?>
<!--suppress UnresolvedMavenProperty -->
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.trivago.rta</groupId>
    <artifactId>cucable-test-project</artifactId>
    <version>1.5.1</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <maven.failsafe.plugin.version>3.0.0-M3</maven.failsafe.plugin.version>
        <maven.build.helper.plugin.version>3.0.0</maven.build.helper.plugin.version>
        <cucumber.version>4.2.6</cucumber.version>
        <maven.compiler.plugin.version>3.7.0</maven.compiler.plugin.version>

        <generated.runner.directory>${project.build.directory}/parallel/runners</generated.runner.directory>
        <generated.feature.directory>${project.build.directory}/parallel/features</generated.feature.directory>
    </properties>

    <dependencies>
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-java</artifactId>
            <version>${cucumber.version}</version>
        </dependency>
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-junit</artifactId>
            <version>${cucumber.version}</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>com.trivago.rta</groupId>
                <artifactId>cucable-plugin</artifactId>
                <version>${project.version}</version>
                <executions>
                    <execution>
                        <id>generate-test-resources</id>
                        <phase>generate-test-resources</phase>
                        <goals>
                            <goal>parallel</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <sourceRunnerTemplateFile>src/test/java/some/template/CucableJavaTemplate.java
                    </sourceRunnerTemplateFile>
                    <sourceFeatures>src/test/resources/features</sourceFeatures>

                    <generatedFeatureDirectory>${generated.feature.directory}</generatedFeatureDirectory>
                    <generatedRunnerDirectory>${generated.runner.directory}</generatedRunnerDirectory>

                </configuration>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>build-helper-maven-plugin</artifactId>
                <version>${maven.build.helper.plugin.version}</version>
                <executions>
                    <execution>
                        <id>add-test-source</id>
                        <phase>generate-test-sources</phase>
                        <goals>
                            <goal>add-test-source</goal>
                        </goals>
                        <configuration>
                            <sources>
                                <source>${generated.runner.directory}</source>
                            </sources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>${maven.failsafe.plugin.version}</version>
                <executions>
                    <execution>
                        <id>Run parallel tests</id>
                        <phase>integration-test</phase>
                        <goals>
                            <goal>integration-test</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <forkCount>5</forkCount>
                    <testFailureIgnore>true</testFailureIgnore>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven.compiler.plugin.version}</version>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
</code>```

答:
Key Point :

We shall not mix direct & transitive dependencies specially their versions! Doing so can cause unpredictable outcome.

We would need to use Cucumber-JVM v4.x.x specially to implement parallel execution without using cucumber-jvm-parallel or cucable plugin

We would be considering v4.2.6 for the implementation

Cucumber Parallel Execution via JUnit

First - Update POM.xml with correct set of io.cucumber dependencies.

```<code> <dependency>
    <groupId>io.cucumber</groupId>
    <artifactId>cucumber-junit</artifactId>
    <version>4.2.6</version>
</dependency>

<dependency>
    <groupId>io.cucumber</groupId>
    <artifactId>cucumber-picocontainer</artifactId>
    <version>4.2.6</version>
</dependency>
</code>```

Point To Note Down - There could be an issue like everything is ok but still tests do not execute in parallel and could be if your pom.xml is having direct/transitive dependency of testng. As testNG causes Surefire to ignore JUnit wrapper class. If you had testng dependency so remove the TestNG dependency or you can take a call to 2 define 2 execution - For TestNG & JUnit and disable one as per your need.

Second - Customize Runner class as per your framework need

```<code>package com.jacksparrow.automation.suite.runner;

import org.junit.runner.RunWith;
import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;

@RunWith(Cucumber.class)
@CucumberOptions(features = "classpath:features/functional/",
                     glue = {"com.jacksparrow.automation.steps_definitions.functional" },
                   plugin = { "pretty","json:target/cucumber-json/cucumber.json",
                            "junit:target/cucumber-reports/Cucumber.xml", "html:target/cucumber-reports"},
                   tags = { "@BAMS_Submitted_State_Guest_User" },
                   junit ={ "--step-notifications"},
                   strict = false,
                   dryRun = false,
               monochrome = true)

public class RunCukeTest {
}
</code>```

Third - Implementing maven surefire plugin which would actually run tests in parallel

```<code><plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>3.0.0-M3</version>
    <configuration>
        <parallel>methods</parallel>
        <threadCount>2</threadCount>
        <reuserForks>false</reuserForks>
        <testFailureIgnore>true</testFailureIgnore>
        <includes>
            <include>**/*RunCukeTest.java</include>
        </includes>
    </configuration>
</plugin>
</code>```

Fourth - Implement Hooks.java

```<code>import cucumber.api.Scenario;
import cucumber.api.java.Before;
import cucumber.api.java.After;

public class Hooks {

    @Before
    public void setUpScenario(String browser){
        //BaseSteps.getInstance().getBrowserInstantiation(browser); your browser setup method
    }
    @After
    public void afterScenario(Scenario scenario){
    // more code goes here
    }
   }
</code>```

Cucumber Parallel Execution via TestNG

Note : In below implementation, we would be reading browser parameter from TestNG.xml file

First - Update POM.xml with correct set of io.cucumber dependencies.

```<code><dependency>
    <groupId>io.cucumber</groupId>
    <artifactId>cucumber-picocontainer</artifactId>
    <version>4.2.6</version>
</dependency>

<dependency>
    <groupId>io.cucumber</groupId>
    <artifactId>cucumber-testng</artifactId>
    <version>4.2.6</version>
</dependency>
</code>```

Second - Customize TestNGRunner class as per your framework need

```<code>package com.jacksparrow.automation.suite.runner;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Parameters;
import com.jacksparrow.automation.steps_definitions.functional.BaseSteps;
import cucumber.api.CucumberOptions;
import cucumber.api.testng.AbstractTestNGCucumberTests;

@CucumberOptions(features = "classpath:features/functional/",
                     glue = {"com.jacksparrow.automation.steps_definitions.functional" },
                   plugin = { "pretty","json:target/cucumber-json/cucumber.json",
                            "junit:target/cucumber-reports/Cucumber.xml", "html:target/cucumber-reports"},
                   tags = { "@BAMS_Submitted_State_Guest_User" },
                   junit ={ "--step-notifications"},
                   strict = false,
                   dryRun = false,
               monochrome = true)

public class RunCukeTest extends Hooks {

}
</code>```

Third - Implement Hooks.java

```<code>import org.testng.annotations.BeforeClass;
import org.testng.annotations.Parameters;
import cucumber.api.testng.AbstractTestNGCucumberTests;

public class Hooks extends AbstractTestNGCucumberTests {

    @Parameters({ "browser" })
    @BeforeTest
    public void setUpScenario(String browser){
        //BaseSteps.getInstance().getBrowserInstantiation(browser); your browser setup method
    }
}
</code>```

Fourth - Update TestNG.xml under /src/test/resources/ as per your TestNGRunner Class and framework need.

```<code><?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Testng Cucumber Suite" parallel="tests" thread-count="2">
    <test name="SmokeTest">
        <parameter name="browser" value="chrome" />
        <classes>
            <class name="com.cvs.runner.TestSuiteRunner" />
        </classes>
    </test>
</suite>
</code>```

Fifth - You shall be all set to run automation suite using TestNG in any of the following ways

```<code> -    Run TestNG.xml directly from IDE
 -    From CMD - mvn test -Dsurefire.suiteXmlFiles=src/test/resources/testng.xml
 -    From POM.xml - Using Surefire Plugin

<profiles>
   <profile>
      <id>selenium-tests</id>
      <build>
         <plugins>
            <plugin>
               <groupId>org.apache.maven.plugins</groupId>
               <artifactId>maven-surefire-plugin</artifactId>
               <version>3.0.0-M3</version>
               <configuration>
                  <suiteXmlFiles>
                     <suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>
                  </suiteXmlFiles>
               </configuration>
            </plugin>
         </plugins>
      </build>
   </profile>
</profiles>
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I'm trying to run Scenario's in parallel using Trivago's Cucable Plugin. To test it before implementing it my project I download this project.

https://github.com/trivago/cucable-plugin/tree/master/example-project

I tried, mvn clean verify and it created *IT.java files in target folder, but I noticed these are not running in parallel.

How do I know? I added sleep in each statement. Largest sleep is 15 seconds, so the total build should be approx 16 seconds, but it is showing 30 (sum of all sleeps of all scenarios 2+5+15+8) seconds.

cucable.template

import cucumber.api.CucumberOptions;
import org.junit.runner.RunWith;

@RunWith(Cucumber.class)
@CucumberOptions(
        glue = "steps",
        features = {"target/parallel/features/[CUCABLE:FEATURE].feature"},
        plugin = {"json:target/cucumber-report/[CUCABLE:RUNNER].json"}
)
public class [CUCABLE:RUNNER] {
    // [CUCABLE:CUSTOM:comment]
}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.trivago.rta</groupId>
    <artifactId>cucable-test-project</artifactId>
    <version>1.5.1</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <maven.failsafe.plugin.version>3.0.0-M3</maven.failsafe.plugin.version>
        <maven.build.helper.plugin.version>3.0.0</maven.build.helper.plugin.version>
        <cucumber.version>4.2.6</cucumber.version>
        <maven.compiler.plugin.version>3.7.0</maven.compiler.plugin.version>

        <generated.runner.directory>${project.build.directory}/parallel/runners</generated.runner.directory>
        <generated.feature.directory>${project.build.directory}/parallel/features</generated.feature.directory>
    </properties>

    <dependencies>
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-java</artifactId>
            <version>${cucumber.version}</version>
        </dependency>
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-junit</artifactId>
            <version>${cucumber.version}</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>com.trivago.rta</groupId>
                <artifactId>cucable-plugin</artifactId>
                <version>${project.version}</version>
                <executions>
                    <execution>
                        <id>generate-test-resources</id>
                        <phase>generate-test-resources</phase>
                        <goals>
                            <goal>parallel</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <sourceRunnerTemplateFile>src/test/java/some/template/CucableJavaTemplate.java
                    </sourceRunnerTemplateFile>
                    <sourceFeatures>src/test/resources/features</sourceFeatures>

                    <generatedFeatureDirectory>${generated.feature.directory}</generatedFeatureDirectory>
                    <generatedRunnerDirectory>${generated.runner.directory}</generatedRunnerDirectory>

                </configuration>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>build-helper-maven-plugin</artifactId>
                <version>${maven.build.helper.plugin.version}</version>
                <executions>
                    <execution>
                        <id>add-test-source</id>
                        <phase>generate-test-sources</phase>
                        <goals>
                            <goal>add-test-source</goal>
                        </goals>
                        <configuration>
                            <sources>
                                <source>${generated.runner.directory}</source>
                            </sources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>${maven.failsafe.plugin.version}</version>
                <executions>
                    <execution>
                        <id>Run parallel tests</id>
                        <phase>integration-test</phase>
                        <goals>
                            <goal>integration-test</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <forkCount>5</forkCount>
                    <testFailureIgnore>true</testFailureIgnore>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven.compiler.plugin.version}</version>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Body:
Key Point :

We shall not mix direct & transitive dependencies specially their versions! Doing so can cause unpredictable outcome.

We would need to use Cucumber-JVM v4.x.x specially to implement parallel execution without using cucumber-jvm-parallel or cucable plugin

We would be considering v4.2.6 for the implementation

Cucumber Parallel Execution via JUnit

First - Update POM.xml with correct set of io.cucumber dependencies.

 <dependency>
    <groupId>io.cucumber</groupId>
    <artifactId>cucumber-junit</artifactId>
    <version>4.2.6</version>
</dependency>

<dependency>
    <groupId>io.cucumber</groupId>
    <artifactId>cucumber-picocontainer</artifactId>
    <version>4.2.6</version>
</dependency>

Point To Note Down - There could be an issue like everything is ok but still tests do not execute in parallel and could be if your pom.xml is having direct/transitive dependency of testng. As testNG causes Surefire to ignore JUnit wrapper class. If you had testng dependency so remove the TestNG dependency or you can take a call to 2 define 2 execution - For TestNG & JUnit and disable one as per your need.

Second - Customize Runner class as per your framework need

package com.jacksparrow.automation.suite.runner;

import org.junit.runner.RunWith;
import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;

@RunWith(Cucumber.class)
@CucumberOptions(features = "classpath:features/functional/",
                     glue = {"com.jacksparrow.automation.steps_definitions.functional" },
                   plugin = { "pretty","json:target/cucumber-json/cucumber.json",
                            "junit:target/cucumber-reports/Cucumber.xml", "html:target/cucumber-reports"},
                   tags = { "@BAMS_Submitted_State_Guest_User" },
                   junit ={ "--step-notifications"},
                   strict = false,
                   dryRun = false,
               monochrome = true)

public class RunCukeTest {
}

Third - Implementing maven surefire plugin which would actually run tests in parallel

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>3.0.0-M3</version>
    <configuration>
        <parallel>methods</parallel>
        <threadCount>2</threadCount>
        <reuserForks>false</reuserForks>
        <testFailureIgnore>true</testFailureIgnore>
        <includes>
            <include>**/*RunCukeTest.java</include>
        </includes>
    </configuration>
</plugin>

Fourth - Implement Hooks.java

import cucumber.api.Scenario;
import cucumber.api.java.Before;
import cucumber.api.java.After;

public class Hooks {

    @Before
    public void setUpScenario(String browser){
        //BaseSteps.getInstance().getBrowserInstantiation(browser); your browser setup method
    }
    @After
    public void afterScenario(Scenario scenario){
    // more code goes here
    }
   }

Cucumber Parallel Execution via TestNG

Note : In below implementation, we would be reading browser parameter from TestNG.xml file

First - Update POM.xml with correct set of io.cucumber dependencies.

<dependency>
    <groupId>io.cucumber</groupId>
    <artifactId>cucumber-picocontainer</artifactId>
    <version>4.2.6</version>
</dependency>

<dependency>
    <groupId>io.cucumber</groupId>
    <artifactId>cucumber-testng</artifactId>
    <version>4.2.6</version>
</dependency>

Second - Customize TestNGRunner class as per your framework need

package com.jacksparrow.automation.suite.runner;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Parameters;
import com.jacksparrow.automation.steps_definitions.functional.BaseSteps;
import cucumber.api.CucumberOptions;
import cucumber.api.testng.AbstractTestNGCucumberTests;

@CucumberOptions(features = "classpath:features/functional/",
                     glue = {"com.jacksparrow.automation.steps_definitions.functional" },
                   plugin = { "pretty","json:target/cucumber-json/cucumber.json",
                            "junit:target/cucumber-reports/Cucumber.xml", "html:target/cucumber-reports"},
                   tags = { "@BAMS_Submitted_State_Guest_User" },
                   junit ={ "--step-notifications"},
                   strict = false,
                   dryRun = false,
               monochrome = true)

public class RunCukeTest extends Hooks {

}

Third - Implement Hooks.java

import org.testng.annotations.BeforeClass;
import org.testng.annotations.Parameters;
import cucumber.api.testng.AbstractTestNGCucumberTests;

public class Hooks extends AbstractTestNGCucumberTests {

    @Parameters({ "browser" })
    @BeforeTest
    public void setUpScenario(String browser){
        //BaseSteps.getInstance().getBrowserInstantiation(browser); your browser setup method
    }
}

Fourth - Update TestNG.xml under /src/test/resources/ as per your TestNGRunner Class and framework need.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Testng Cucumber Suite" parallel="tests" thread-count="2">
    <test name="SmokeTest">
        <parameter name="browser" value="chrome" />
        <classes>
            <class name="com.cvs.runner.TestSuiteRunner" />
        </classes>
    </test>
</suite>

Fifth - You shall be all set to run automation suite using TestNG in any of the following ways

 -    Run TestNG.xml directly from IDE
 -    From CMD - mvn test -Dsurefire.suiteXmlFiles=src/test/resources/testng.xml
 -    From POM.xml - Using Surefire Plugin

<profiles>
   <profile>
      <id>selenium-tests</id>
      <build>
         <plugins>
            <plugin>
               <groupId>org.apache.maven.plugins</groupId>
               <artifactId>maven-surefire-plugin</artifactId>
               <version>3.0.0-M3</version>
               <configuration>
                  <suiteXmlFiles>
                     <suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>
                  </suiteXmlFiles>
               </configuration>
            </plugin>
         </plugins>
      </build>
   </profile>
</profiles>


问:
get the compiler to read a string as a variable
I am trying to play a random audio clip in a game I am making in Phaser 3. I wish to play any of the following when a certain event happens:

```<code>audioBanshee0 = this.sound.add('audioBanshee0',{volume: 0.5});
audioBanshee1 = this.sound.add('audioBanshee1',{volume: 0.5});
audioBanshee2 = this.sound.add('audioBanshee2',{volume: 0.5});
audioBanshee3 = this.sound.add('audioBanshee3',{volume: 0.5});
audioBanshee4 = this.sound.add('audioBanshee4',{volume: 0.5});
</code>```

I have tried the following:

```<code>var ref = Math.floor(Math.random() * Math.floor(5));
const audioBansheeScreech = "audioBanshee" + ref;
audioBansheeScreech.play();
</code>```

I get an error saying

audioBansheeScreech.play() is not a function

because audioBansheeScreech is a string. I can see round this with for loops and if statements, but I would much rather avoid.

答:
It may be easier to move these into an object, then you can call them by using a string:

```<code>const audioBanshees = {
  audioBanshee0: this.sound.add('audioBanshee0',{volume: 0.5}),
  audioBanshee1: this.sound.add('audioBanshee1',{volume: 0.5}),
  audioBanshee2: this.sound.add('audioBanshee2',{volume: 0.5}),
  audioBanshee3: this.sound.add('audioBanshee3',{volume: 0.5}),
  audioBanshee4: this.sound.add('audioBanshee4',{volume: 0.5})
}

let ref = Math.floor(Math.random() * Math.floor(5));

const audioBansheeScreech = audioBanshees["audioBanshee" + ref];

audioBansheeScreech.play()
</code>```

Though IMO, an array here would be more logical and easier to read:

```<code>const audioBanshees = [
  this.sound.add('audioBanshee0',{volume: 0.5}),
  this.sound.add('audioBanshee1',{volume: 0.5}),
  this.sound.add('audioBanshee2',{volume: 0.5}),
  this.sound.add('audioBanshee3',{volume: 0.5}),
  this.sound.add('audioBanshee4',{volume: 0.5})
]

let ref = Math.floor(Math.random() * Math.floor(5));

const audioBansheeScreech = audioBanshees[ref];

audioBansheeScreech.play()
</code>```

Body:
I am trying to play a random audio clip in a game I am making in Phaser 3. I wish to play any of the following when a certain event happens:

audioBanshee0 = this.sound.add('audioBanshee0',{volume: 0.5});
audioBanshee1 = this.sound.add('audioBanshee1',{volume: 0.5});
audioBanshee2 = this.sound.add('audioBanshee2',{volume: 0.5});
audioBanshee3 = this.sound.add('audioBanshee3',{volume: 0.5});
audioBanshee4 = this.sound.add('audioBanshee4',{volume: 0.5});

I have tried the following:

var ref = Math.floor(Math.random() * Math.floor(5));
const audioBansheeScreech = "audioBanshee" + ref;
audioBansheeScreech.play();

I get an error saying

audioBansheeScreech.play() is not a function

because audioBansheeScreech is a string. I can see round this with for loops and if statements, but I would much rather avoid.

Body:
It may be easier to move these into an object, then you can call them by using a string:

const audioBanshees = {
  audioBanshee0: this.sound.add('audioBanshee0',{volume: 0.5}),
  audioBanshee1: this.sound.add('audioBanshee1',{volume: 0.5}),
  audioBanshee2: this.sound.add('audioBanshee2',{volume: 0.5}),
  audioBanshee3: this.sound.add('audioBanshee3',{volume: 0.5}),
  audioBanshee4: this.sound.add('audioBanshee4',{volume: 0.5})
}

let ref = Math.floor(Math.random() * Math.floor(5));

const audioBansheeScreech = audioBanshees["audioBanshee" + ref];

audioBansheeScreech.play()

Though IMO, an array here would be more logical and easier to read:

const audioBanshees = [
  this.sound.add('audioBanshee0',{volume: 0.5}),
  this.sound.add('audioBanshee1',{volume: 0.5}),
  this.sound.add('audioBanshee2',{volume: 0.5}),
  this.sound.add('audioBanshee3',{volume: 0.5}),
  this.sound.add('audioBanshee4',{volume: 0.5})
]

let ref = Math.floor(Math.random() * Math.floor(5));

const audioBansheeScreech = audioBanshees[ref];

audioBansheeScreech.play()


问:
How to declare a variable in MySQL?
How to declare a variable in mysql, so that my second query can use it?

I would like to write something like:

```<code>SET start = 1;
SET finish = 10;

SELECT * FROM places WHERE place BETWEEN start AND finish;
</code>```

答:
SET Value

```<code> declare @Regione int;
 set @Regione=(select  id from users
 where id=1) ;
 select @Regione ;
</code>```

ContentLicense: CC BY-SA 3.0

Title: How to declare a variable in MySQL?

Body:
How to declare a variable in mysql, so that my second query can use it?

I would like to write something like:

SET start = 1;
SET finish = 10;

SELECT * FROM places WHERE place BETWEEN start AND finish;

Body:
SET Value

 declare @Regione int;
 set @Regione=(select  id from users
 where id=1) ;
 select @Regione ;


问:
flutter automatic testing : Tap on a button don't work in drawer
I'm trying to do some TDD with flutter and when the test is running,  tapping on a button doesn't work if it's in a drawer. The button works perfectly fine with a normal user.

In the following example we press on two buttons which print a message in the console. Here's the actions :

locate and tap on a button in the scaffold: OK

open the drawer: OK

Locate button in drawer: OK

Tap on the drawer button: nothing happen

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

void main() {
  testWidgets('Test that drawer is apparing and we can click on button',
  (WidgetTester tester) async {
final scaffoldKey = GlobalKey<ScaffoldState>();

await tester.pumpWidget(new MaterialApp(
  title: 'Where Assistant',
  home: Scaffold(
    key: scaffoldKey,
    body: Column(
      children: <Widget>[
        Text('test text'),
        RaisedButton(
          onPressed: () {
            print('OK on main screen');
          },
          child: Icon(Icons.access_alarm),
        ),
      ],
    ),
    drawer: Drawer(
      // Add a ListView to the drawer. This ensures the user can scroll
      // through the options in the Drawer if there isn't enough vertical
      // space to fit everything.
      child: ListView(
        // Important: Remove any padding from the ListView.
        padding: EdgeInsets.zero,
        children: <Widget>[
          DrawerHeader(
            child: Text('Drawer Header'),
            decoration: BoxDecoration(
              color: Colors.blue,
            ),
          ),
          ListTile(
            title: Text('Item 2'),
            onTap: () {
              // Update the state of the app
              // ...
            },
          ),
          RaisedButton(
            onPressed: () {
              print('OK drawer');
            },
            child: Icon(Icons.add),
          )
        ],
      ),
    ),
  ),
));

await tester.pump();

expect(find.text('test text'), findsOneWidget);
expect(find.byIcon(Icons.access_alarm), findsOneWidget);
await tester.tap(find.byIcon(Icons.access_alarm));
expect(find.byIcon(Icons.add), findsNothing);

scaffoldKey.currentState.openDrawer();
await tester.pump(); // drawer should appear

expect(find.text('Item 2'), findsOneWidget);
expect(find.byIcon(Icons.add), findsOneWidget);
await tester.tap(find.byIcon(Icons.add));
print('end of test');
  });
}
</code>```

答:
finally found a workaround : just need to add some delay before tapping in the drawer.

So I added

```<code>await tester.pump(const Duration(milliseconds: 100));
</code>```

before tapping on buttons

Body:
I'm trying to do some TDD with flutter and when the test is running,  tapping on a button doesn't work if it's in a drawer. The button works perfectly fine with a normal user.

In the following example we press on two buttons which print a message in the console. Here's the actions :

locate and tap on a button in the scaffold: OK

open the drawer: OK

Locate button in drawer: OK

Tap on the drawer button: nothing happen

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

void main() {
  testWidgets('Test that drawer is apparing and we can click on button',
  (WidgetTester tester) async {
final scaffoldKey = GlobalKey<ScaffoldState>();

await tester.pumpWidget(new MaterialApp(
  title: 'Where Assistant',
  home: Scaffold(
    key: scaffoldKey,
    body: Column(
      children: <Widget>[
        Text('test text'),
        RaisedButton(
          onPressed: () {
            print('OK on main screen');
          },
          child: Icon(Icons.access_alarm),
        ),
      ],
    ),
    drawer: Drawer(
      // Add a ListView to the drawer. This ensures the user can scroll
      // through the options in the Drawer if there isn't enough vertical
      // space to fit everything.
      child: ListView(
        // Important: Remove any padding from the ListView.
        padding: EdgeInsets.zero,
        children: <Widget>[
          DrawerHeader(
            child: Text('Drawer Header'),
            decoration: BoxDecoration(
              color: Colors.blue,
            ),
          ),
          ListTile(
            title: Text('Item 2'),
            onTap: () {
              // Update the state of the app
              // ...
            },
          ),
          RaisedButton(
            onPressed: () {
              print('OK drawer');
            },
            child: Icon(Icons.add),
          )
        ],
      ),
    ),
  ),
));

await tester.pump();

expect(find.text('test text'), findsOneWidget);
expect(find.byIcon(Icons.access_alarm), findsOneWidget);
await tester.tap(find.byIcon(Icons.access_alarm));
expect(find.byIcon(Icons.add), findsNothing);

scaffoldKey.currentState.openDrawer();
await tester.pump(); // drawer should appear

expect(find.text('Item 2'), findsOneWidget);
expect(find.byIcon(Icons.add), findsOneWidget);
await tester.tap(find.byIcon(Icons.add));
print('end of test');
  });
}

Body:
finally found a workaround : just need to add some delay before tapping in the drawer.

So I added

await tester.pump(const Duration(milliseconds: 100));

before tapping on buttons


问:
Strange behaviour of my code with strtotime
I'm having some headaches with dates in PHP. I'm getting some data from a form and trying to "submit" it with an ajax call to update the web without reloading the page.

I have a datepicker which allows to pick a range of dates and so, I've done a dirty function to separate the start and the end date and posting it to PHP separately (in case a range of dates where selected). They are formated in this way: 01/04/2011,08/04/2011

In the PHP so I have the dates variables and try to format them to perform some database queries in this ways:

```<code>$date_start = $_POST['date_start'];
$date_start_form = date("Y-m-d",  strtotime($date_start));
</code>```

After some testing I have discovered that if the date is higher to day 12 of whichever month, and then try to format it, it gives me back 1970-01-01.

Does someone know why this happen?

答:
If you use php=>5.3, it might worth looking at DateTime::createFromFormat function.
For your case it may be implemented like:</p>

```<code>$date = "08/04/2011";
$date_object = DateTime::createFromFormat('d/m/y', $date);
$timestamp = $date_object->getTimestamp();
</code>```

Body:
I'm having some headaches with dates in PHP. I'm getting some data from a form and trying to "submit" it with an ajax call to update the web without reloading the page.

I have a datepicker which allows to pick a range of dates and so, I've done a dirty function to separate the start and the end date and posting it to PHP separately (in case a range of dates where selected). They are formated in this way: 01/04/2011,08/04/2011

In the PHP so I have the dates variables and try to format them to perform some database queries in this ways:

$date_start = $_POST['date_start'];
$date_start_form = date("Y-m-d",  strtotime($date_start));

After some testing I have discovered that if the date is higher to day 12 of whichever month, and then try to format it, it gives me back 1970-01-01.

Does someone know why this happen?

Body:
If you use php=>5.3, it might worth looking at DateTime::createFromFormat function.
For your case it may be implemented like:

$date = "08/04/2011";
$date_object = DateTime::createFromFormat('d/m/y', $date);
$timestamp = $date_object->getTimestamp();


问:
Angular StaticInjectorError with Material Snackbar
I want to add Material Snackbar to my app as a Service.

So, in my notification.service.ts, I added:

```<code>import { Component, Input, Output, EventEmitter } from '@angular/core';
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';

@Injectable()
export class NotificationService {

  snackbar_notification: Subject<string> = new Subject();
  constructor() {}
  setSnackbarNotification(message: string) {
    this.snackbar_notification.next(message);
  }
}
</code>```

In my app.component.ts:

```<code>export class AppComponent implements OnInit {

  constructor(
    private notificationService: NotificationService,
    public snackBar: MatSnackBar
  ) {

    this.notificationService.snackbar_notification.subscribe(message => {
      this.snackBar.open(message);
    });

  }
}
</code>```

I trigger the snackbar from a component like:

```<code>this.notificationService.setSnackbarNotification('this is a notification');
</code>```

The code was working fine before I made the above changes in above 3 files.

Now, it's giving me error during execution:

```<code>Error: StaticInjectorError(Xs)[e -> e]:
  StaticInjectorError(Platform: core)[e -> e]:
    NullInjectorError: No provider for e!
</code>```

How can I solve this?

答:
Import the module:

```<code>import {MatSnackBarModule} from '@angular/material/snack-bar';
</code>```

And add it to your module:

```<code>@NgModule({
    imports: [
        MatSnackBarModule,
    ],
    providers: [

    ],
})
</code>```

Make sure you are adding to the parent module of notification and component you are using in it.

Body:
I want to add Material Snackbar to my app as a Service.

So, in my notification.service.ts, I added:

import { Component, Input, Output, EventEmitter } from '@angular/core';
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';

@Injectable()
export class NotificationService {

  snackbar_notification: Subject<string> = new Subject();
  constructor() {}
  setSnackbarNotification(message: string) {
    this.snackbar_notification.next(message);
  }
}

In my app.component.ts:

export class AppComponent implements OnInit {

  constructor(
    private notificationService: NotificationService,
    public snackBar: MatSnackBar
  ) {

    this.notificationService.snackbar_notification.subscribe(message => {
      this.snackBar.open(message);
    });

  }
}

I trigger the snackbar from a component like:

this.notificationService.setSnackbarNotification('this is a notification');

The code was working fine before I made the above changes in above 3 files.

Now, it's giving me error during execution:

Error: StaticInjectorError(Xs)[e -> e]:
  StaticInjectorError(Platform: core)[e -> e]:
    NullInjectorError: No provider for e!

How can I solve this?

Body:
Import the module:

import {MatSnackBarModule} from '@angular/material/snack-bar';

And add it to your module:

@NgModule({
    imports: [
        MatSnackBarModule,
    ],
    providers: [

    ],
})

Make sure you are adding to the parent module of notification and component you are using in it.


问:
Best possible ways to copy link
I'm looking for a suitable way to copy URL (link) to the clipboard.

Can someone tell me how this can be achieved?

function copyURL() {
  var elem = document.createElement("textarea");
  document.body.appendChild(elem);
  elem.value = google.com;
  elem.select();
  document.execCommand("copy");
  document.body.removeChild(elem);
  document.write("Copied to clipboard!");
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code>Copy URL</code>```

答:
You can use

document.execCommand("copy");

Fiddle:  Fiddle

Title: Best possible ways to copy link

Body:
I'm looking for a suitable way to copy URL (link) to the clipboard.

Can someone tell me how this can be achieved?

function copyURL() {
  var elem = document.createElement("textarea");
  document.body.appendChild(elem);
  elem.value = google.com;
  elem.select();
  document.execCommand("copy");
  document.body.removeChild(elem);
  document.write("Copied to clipboard!");
}

Copy URL


问:
Dynamic number of inputs for a function in python
What is the difference between using *args and getting a list as input for having a dynamic number of inputs for a function.

Do these two ways have any advantages in comparison with the other?

答:
It's just a difference in what type of arguments the function expects. They are fairly interchangeable; which you choose is mostly a matter of preference (though see the exceptions at the end of the answer).

Given the following definitions:

```<code># Separate arguments
def foo(*args):
    pass

# Single sequence of arguments
def bar(list_of_args):
    pass

x = [1, 2, 3]
</code>```

These two calls are equivalent:

```<code>foo(1, 2, 3)
foo(*x)      # Unpack a list before calling
</code>```

And these two calls are equivalent:

```<code>bar(x)
bar([1, 2, 3])  # Explicitly pack individual arguments
</code>```

You mentioned **args in your question. The name of the parameter isn't really important; the special behavior is indicated by a parameter name beginning with one or two *s. One * indicates arbitrary positional arguments, as shown above. Two *s indicates arbitrary keyword arguments. Conventionally, the two most common names are *args and **kwargs.

A brief example similar to the above:

```<code># Arbitrary keyword arguments
def foo(**kwargs):
    pass

# Single dict d
def bar(d):
    pass

d = {'a': 1, 'b': 2}

# Equivalent
foo(*d)
foo(a=1, b=2)

# Equivalent
bar(d)
bar(dict(a=1, b=2))
</code>```

Exception: if the function actually expects to mutate a value, you can't replace that effectively with a */** parameter. Example:

```<code>def foo(**kwargs):
    kwargs['foo'] = 3
</code>```

This adds a mapping of 'foo' to 3 to the dictionary, but it is a temporary dictionary created just for the call to foo. Nothing outside the function has a reference to that dictionary, so the update doesn't have any effect after foo returns.

Similar logic applies to *args, but since args is a tuple, and tuples are immutable, there's little you could do with the argument anyway. That said, if the function really expects a list, and not just an arbitrary sequence of arguments, you have to define your function to handle that.

```<code>def foo(some_list):    # can't use *args here
    some_list.append(3)
</code>```

You can't effectively define that as

```<code>def foo(*args):
    args.append(3)
</code>```

because foo receives a temporary tuple, not a list object that

Body:
It's just a difference in what type of arguments the function expects. They are fairly interchangeable; which you choose is mostly a matter of preference (though see the exceptions at the end of the answer).

Given the following definitions:

# Separate arguments
def foo(*args):
    pass

# Single sequence of arguments
def bar(list_of_args):
    pass

x = [1, 2, 3]

These two calls are equivalent:

foo(1, 2, 3)
foo(*x)      # Unpack a list before calling

And these two calls are equivalent:

bar(x)
bar([1, 2, 3])  # Explicitly pack individual arguments

You mentioned **args in your question. The name of the parameter isn't really important; the special behavior is indicated by a parameter name beginning with one or two *s. One * indicates arbitrary positional arguments, as shown above. Two *s indicates arbitrary keyword arguments. Conventionally, the two most common names are *args and **kwargs.

A brief example similar to the above:

# Arbitrary keyword arguments
def foo(**kwargs):
    pass

# Single dict d
def bar(d):
    pass

d = {'a': 1, 'b': 2}

# Equivalent
foo(*d)
foo(a=1, b=2)

# Equivalent
bar(d)
bar(dict(a=1, b=2))

Exception: if the function actually expects to mutate a value, you can't replace that effectively with a */** parameter. Example:

def foo(**kwargs):
    kwargs['foo'] = 3

This adds a mapping of 'foo' to 3 to the dictionary, but it is a temporary dictionary created just for the call to foo. Nothing outside the function has a reference to that dictionary, so the update doesn't have any effect after foo returns.

Similar logic applies to *args, but since args is a tuple, and tuples are immutable, there's little you could do with the argument anyway. That said, if the function really expects a list, and not just an arbitrary sequence of arguments, you have to define your function to handle that.

def foo(some_list):    # can't use *args here
    some_list.append(3)

You can't effectively define that as

def foo(*args):
    args.append(3)

because foo receives a temporary tuple, not a list object that


问:
Using regex to tell csplit where to split the file
I have a large text file with content set up like this:

```<code>---
title: Lorim Ipsum Dolar
---
Lorim ipsum content
---
title: Excelvier whatever
---
Lorim ipsum content goes here.
</code>```

I'm trying to split up this file into individual files using csplit.

The individual files would have content formatted like this:

```<code>---
title: Lorim Ipsum Dolar
---
Lorim ipsum content
</code>```

I was hoping to be able to regex the ---, newline & title like so ---\ntitle

But I'm not able to select it with…

```<code>csplit -k products.txt '/---[^\n]title/' {99}
</code>```

I've tried lots of variations to no avail. I keeping getting "no match".

答:
For me, the answer was don't use csplit, use awk.

```<code>awk '
/^title:/ {++count; file="file"count".txt"; print file}
file {print line > file}
{line=$0}
' products.txt
</code>```

The first command declares a new file when title: is encoutered. The second command writes the preceding line to file if file has been declared. The third command assigns the current line to a variable.

Body:
I have a large text file with content set up like this:

---
title: Lorim Ipsum Dolar
---
Lorim ipsum content
---
title: Excelvier whatever
---
Lorim ipsum content goes here.

I'm trying to split up this file into individual files using csplit.

The individual files would have content formatted like this:

---
title: Lorim Ipsum Dolar
---
Lorim ipsum content

I was hoping to be able to regex the ---, newline & title like so ---\ntitle

But I'm not able to select it with…

csplit -k products.txt '/---[^\n]title/' {99}

I've tried lots of variations to no avail. I keeping getting "no match".

Body:
For me, the answer was don't use csplit, use awk.

awk '
/^title:/ {++count; file="file"count".txt"; print file}
file {print line > file}
{line=$0}
' products.txt

The first command declares a new file when title: is encoutered. The second command writes the preceding line to file if file has been declared. The third command assigns the current line to a variable.


问:
ExtJS with a .NET backend
What's my best option (using the latest in the .NET framework) for creating a webapp with with a complete ExtJS frontend (all server interaction happens through AJAX with XML or JSON)? Are there any problems with using WCF? The following (fake, but funny) O'Reilly book cover seems to imply so.

http://www.oreillymaker.com/link/14746/extjswcf/

答:
I've successfully used ExtJS with "old" .NET JSON Web Services.  I tried using WCF DataContracts and all that to begin with but there was too much friction involved.

The one gotcha is that all responses get wrapped in a ".d" property when serialized to JSON.  You need to override the Ext JsonReader class to read the .d property as the response.

See: http://extjs.com/forum/showthread.php?t=59903

OwnerDisplayName: Abdullah Jibaly

ContentLicense: CC BY-SA 2.5

Title: ExtJS with a .NET backend

OwnerDisplayName: ifwdev


问:
How can I fix ODOO 9 mismatching shipping address between [/shop/checkout] and [/payment] in Website sale Module?
My problem is that if I select a shipping address in the checkout page of website (between various addresses available for that user) and click CONFIRM, in the next page the shipping address is not what I selected previously.

Seems like odoo is loosing track of the ID of the address I want (with parent_id linked to the user) and set always the same one.

Anybody else has encountered this issue? Why shipping id won't remain 85262?

I tried debugging the code but I can't understand what is causing this problem.

Many thanks

[CHECKOUT] https://github.com/odoo/odoo/blob/9.0/addons/website_sale/controllers/main.py

```<code>PARTNER SHIPPING ID [inizio] CONFIRM ORDER >>> :: :: 85261

2019-05-30 09:00:25,262 11905 DEBUG retail openerp.addons.website_sale.controllers.main:

 ShippingID TRY:: :: 85262

2019-05-30 09:00:25,266 11905 DEBUG retail openerp.addons.website_sale.controllers.main:

 ShippingID (CHECKOUT VALUES):: :: 85262

2019-05-30 09:00:25,266 11905 DEBUG retail openerp.addons.website_sale.controllers.main:

 Values AL TERMINE DI CHECKOUT:: :: {'states': res.country.state(1, 10, 9, 12, 11, 13, 14, 15, 17, 16, 18, 19, 20, 24, 21, 22, 23, 25, 26, 27, 42, 41, 28, 43, 44, 46, 45, 29, 36, 37, 30, 32, 33, 34, 2, 3, 31, 35, 38, 39, 40, 47, 4, 48, 5, 49, 50, 6, 51, 52, 53, 55, 7, 54, 8, 56, 58, 57, 59), 'has_check_vat': True, 'only_services': False, 'shipping_id': 85262, 'countries': res.country(3, 16, 6, 63, 12, 1, 9, 5, 10, 4, 11, 7, 15, 14, 13, 17, 33, 24, 20, 19, 37, 21, 38, 26, 28, 34, 30, 31, 18, 36, 35, 32, 106, 29, 23, 22, 25, 117, 48, 39, 53, 124, 41, 216, 47, 49, 55, 40, 50, 119, 43, 42, 46, 51, 98, 52, 54, 56, 57, 60, 59, 61, 62, 225, 64, 66, 211, 88, 68, 65, 70, 73, 75, 72, 71, 76, 80, 217, 77, 85, 79, 58, 81, 82, 89, 84, 78, 87, 92, 91, 83, 86, 93, 94, 99, 96, 238, 97, 95, 100, 109, 105, 101, 108, 107, 102, 104, 103, 110, 45, 112, 114, 111, 113, 125, 115, 118, 123, 116, 126, 135, 127, 132, 131, 136, 129, 133, 134, 148, 144, 142, 156, 158, 155, 145, 153, 143, 150, 151, 154, 248, 157, 74, 139, 138, 147, 140, 152, 137, 159, 146, 160, 169, 168, 166, 8, 170, 161, 172, 165, 162, 164, 171, 163, 149, 121, 167, 173, 179, 186, 184, 174, 177, 187, 175, 178, 182, 180, 176, 185, 183, 188, 189, 190, 192, 193, 27, 200, 120, 128, 141, 181, 210, 239, 246, 205, 194, 206, 191, 196, 204, 199, 212, 203, 201, 195, 207, 250, 90, 122, 209, 69, 130, 197, 208, 202, 214, 198, 44, 213, 229, 220, 230, 219, 218, 221, 224, 227, 223, 226, 222, 215, 228, 232, 231, 2, 233, 235, 236, 234, 237, 244, 240, 243, 241, 242, 245, 67, 247, 249, 252, 251, 253), 'shippings': res.partner(85262,), 'error': {}, 'checkout': {'city': u'citt\xe0 invisibile', 'name': u'aaa-pluto', 'zip': u'17325', 'shipping_name': u'via Pisa', 'shipping_state_id': 15, 'street2': u'via questa', 'shipping_street': u'via pisa', 'country_id': 235, 'shipping_id': 85262, 'phone': u'2', 'shipping_zip': u'17325', 'street': u'strada per fatturazione', 'shipping_country_id': 235, 'state_id': 15, 'email': u'pluto@doglover.com', 'vat': u'', 'shipping_city': u'livorno'}}

2019-05-30 09:00:25,266 11905 DEBUG retail openerp.addons.website_sale.controllers.main:

 Values ORDER :: :: {'states': res.country.state(1, 10, 9, 12, 11, 13, 14, 15, 17, 16, 18, 19, 20, 24, 21, 22, 23, 25, 26, 27, 42, 41, 28, 43, 44, 46, 45, 29, 36, 37, 30, 32, 33, 34, 2, 3, 31, 35, 38, 39, 40, 47, 4, 48, 5, 49, 50, 6, 51, 52, 53, 55, 7, 54, 8, 56, 58, 57, 59), 'has_check_vat': True, 'only_services': False, 'shipping_id': 85262, 'countries': res.country(3, 16, 6, 63, 12, 1, 9, 5, 10, 4, 11, 7, 15, 14, 13, 17, 33, 24, 20, 19, 37, 21, 38, 26, 28, 34, 30, 31, 18, 36, 35, 32, 106, 29, 23, 22, 25, 117, 48, 39, 53, 124, 41, 216, 47, 49, 55, 40, 50, 119, 43, 42, 46, 51, 98, 52, 54, 56, 57, 60, 59, 61, 62, 225, 64, 66, 211, 88, 68, 65, 70, 73, 75, 72, 71, 76, 80, 217, 77, 85, 79, 58, 81, 82, 89, 84, 78, 87, 92, 91, 83, 86, 93, 94, 99, 96, 238, 97, 95, 100, 109, 105, 101, 108, 107, 102, 104, 103, 110, 45, 112, 114, 111, 113, 125, 115, 118, 123, 116, 126, 135, 127, 132, 131, 136, 129, 133, 134, 148, 144, 142, 156, 158, 155, 145, 153, 143, 150, 151, 154, 248, 157, 74, 139, 138, 147, 140, 152, 137, 159, 146, 160, 169, 168, 166, 8, 170, 161, 172, 165, 162, 164, 171, 163, 149, 121, 167, 173, 179, 186, 184, 174, 177, 187, 175, 178, 182, 180, 176, 185, 183, 188, 189, 190, 192, 193, 27, 200, 120, 128, 141, 181, 210, 239, 246, 205, 194, 206, 191, 196, 204, 199, 212, 203, 201, 195, 207, 250, 90, 122, 209, 69, 130, 197, 208, 202, 214, 198, 44, 213, 229, 220, 230, 219, 218, 221, 224, 227, 223, 226, 222, 215, 228, 232, 231, 2, 233, 235, 236, 234, 237, 244, 240, 243, 241, 242, 245, 67, 247, 249, 252, 251, 253), 'shippings': res.partner(85262,), 'error': {}, 'checkout': {'city': u'citt\xe0 invisibile', 'name': u'aaa-pluto', 'zip': u'17325', 'shipping_name': u'via Pisa', 'shipping_state_id': 15, 'street2': u'via questa', 'shipping_street': u'via pisa', 'country_id': 235, 'shipping_id': 85262, 'phone': u'2', 'shipping_zip': u'17325', 'street': u'strada per fatturazione', 'shipping_country_id': 235, 'state_id': 15, 'email': u'pluto@doglover.com', 'vat': u'', 'shipping_city': u'livorno'}}

2019-05-30 09:00:26,836 11905 DEBUG retail openerp.addons.website_sale.controllers.main:

 PARTNER SHIPPING ID [fine] CONFIRM ORDER >>> :: :: 85261
</code>```

答:
Add loop "for record_or_somthing in self: " before your condition and replace self in condition by "record_or_somthing".

for exemple :

```<code>         for record in self:
            if record.invoice_count >= 1:
                record.client_actif = True

            else:
                record.client_actif = False
</code>```

Body:
My problem is that if I select a shipping address in the checkout page of website (between various addresses available for that user) and click CONFIRM, in the next page the shipping address is not what I selected previously.

Seems like odoo is loosing track of the ID of the address I want (with parent_id linked to the user) and set always the same one.

Anybody else has encountered this issue? Why shipping id won't remain 85262?

I tried debugging the code but I can't understand what is causing this problem.

Many thanks

[CHECKOUT] https://github.com/odoo/odoo/blob/9.0/addons/website_sale/controllers/main.py

PARTNER SHIPPING ID [inizio] CONFIRM ORDER >>> :: :: 85261

2019-05-30 09:00:25,262 11905 DEBUG retail openerp.addons.website_sale.controllers.main:

 ShippingID TRY:: :: 85262

2019-05-30 09:00:25,266 11905 DEBUG retail openerp.addons.website_sale.controllers.main:

 ShippingID (CHECKOUT VALUES):: :: 85262

2019-05-30 09:00:25,266 11905 DEBUG retail openerp.addons.website_sale.controllers.main:

 Values AL TERMINE DI CHECKOUT:: :: {'states': res.country.state(1, 10, 9, 12, 11, 13, 14, 15, 17, 16, 18, 19, 20, 24, 21, 22, 23, 25, 26, 27, 42, 41, 28, 43, 44, 46, 45, 29, 36, 37, 30, 32, 33, 34, 2, 3, 31, 35, 38, 39, 40, 47, 4, 48, 5, 49, 50, 6, 51, 52, 53, 55, 7, 54, 8, 56, 58, 57, 59), 'has_check_vat': True, 'only_services': False, 'shipping_id': 85262, 'countries': res.country(3, 16, 6, 63, 12, 1, 9, 5, 10, 4, 11, 7, 15, 14, 13, 17, 33, 24, 20, 19, 37, 21, 38, 26, 28, 34, 30, 31, 18, 36, 35, 32, 106, 29, 23, 22, 25, 117, 48, 39, 53, 124, 41, 216, 47, 49, 55, 40, 50, 119, 43, 42, 46, 51, 98, 52, 54, 56, 57, 60, 59, 61, 62, 225, 64, 66, 211, 88, 68, 65, 70, 73, 75, 72, 71, 76, 80, 217, 77, 85, 79, 58, 81, 82, 89, 84, 78, 87, 92, 91, 83, 86, 93, 94, 99, 96, 238, 97, 95, 100, 109, 105, 101, 108, 107, 102, 104, 103, 110, 45, 112, 114, 111, 113, 125, 115, 118, 123, 116, 126, 135, 127, 132, 131, 136, 129, 133, 134, 148, 144, 142, 156, 158, 155, 145, 153, 143, 150, 151, 154, 248, 157, 74, 139, 138, 147, 140, 152, 137, 159, 146, 160, 169, 168, 166, 8, 170, 161, 172, 165, 162, 164, 171, 163, 149, 121, 167, 173, 179, 186, 184, 174, 177, 187, 175, 178, 182, 180, 176, 185, 183, 188, 189, 190, 192, 193, 27, 200, 120, 128, 141, 181, 210, 239, 246, 205, 194, 206, 191, 196, 204, 199, 212, 203, 201, 195, 207, 250, 90, 122, 209, 69, 130, 197, 208, 202, 214, 198, 44, 213, 229, 220, 230, 219, 218, 221, 224, 227, 223, 226, 222, 215, 228, 232, 231, 2, 233, 235, 236, 234, 237, 244, 240, 243, 241, 242, 245, 67, 247, 249, 252, 251, 253), 'shippings': res.partner(85262,), 'error': {}, 'checkout': {'city': u'citt\xe0 invisibile', 'name': u'aaa-pluto', 'zip': u'17325', 'shipping_name': u'via Pisa', 'shipping_state_id': 15, 'street2': u'via questa', 'shipping_street': u'via pisa', 'country_id': 235, 'shipping_id': 85262, 'phone': u'2', 'shipping_zip': u'17325', 'street': u'strada per fatturazione', 'shipping_country_id': 235, 'state_id': 15, 'email': u'pluto@doglover.com', 'vat': u'', 'shipping_city': u'livorno'}}

2019-05-30 09:00:25,266 11905 DEBUG retail openerp.addons.website_sale.controllers.main:

 Values ORDER :: :: {'states': res.country.state(1, 10, 9, 12, 11, 13, 14, 15, 17, 16, 18, 19, 20, 24, 21, 22, 23, 25, 26, 27, 42, 41, 28, 43, 44, 46, 45, 29, 36, 37, 30, 32, 33, 34, 2, 3, 31, 35, 38, 39, 40, 47, 4, 48, 5, 49, 50, 6, 51, 52, 53, 55, 7, 54, 8, 56, 58, 57, 59), 'has_check_vat': True, 'only_services': False, 'shipping_id': 85262, 'countries': res.country(3, 16, 6, 63, 12, 1, 9, 5, 10, 4, 11, 7, 15, 14, 13, 17, 33, 24, 20, 19, 37, 21, 38, 26, 28, 34, 30, 31, 18, 36, 35, 32, 106, 29, 23, 22, 25, 117, 48, 39, 53, 124, 41, 216, 47, 49, 55, 40, 50, 119, 43, 42, 46, 51, 98, 52, 54, 56, 57, 60, 59, 61, 62, 225, 64, 66, 211, 88, 68, 65, 70, 73, 75, 72, 71, 76, 80, 217, 77, 85, 79, 58, 81, 82, 89, 84, 78, 87, 92, 91, 83, 86, 93, 94, 99, 96, 238, 97, 95, 100, 109, 105, 101, 108, 107, 102, 104, 103, 110, 45, 112, 114, 111, 113, 125, 115, 118, 123, 116, 126, 135, 127, 132, 131, 136, 129, 133, 134, 148, 144, 142, 156, 158, 155, 145, 153, 143, 150, 151, 154, 248, 157, 74, 139, 138, 147, 140, 152, 137, 159, 146, 160, 169, 168, 166, 8, 170, 161, 172, 165, 162, 164, 171, 163, 149, 121, 167, 173, 179, 186, 184, 174, 177, 187, 175, 178, 182, 180, 176, 185, 183, 188, 189, 190, 192, 193, 27, 200, 120, 128, 141, 181, 210, 239, 246, 205, 194, 206, 191, 196, 204, 199, 212, 203, 201, 195, 207, 250, 90, 122, 209, 69, 130, 197, 208, 202, 214, 198, 44, 213, 229, 220, 230, 219, 218, 221, 224, 227, 223, 226, 222, 215, 228, 232, 231, 2, 233, 235, 236, 234, 237, 244, 240, 243, 241, 242, 245, 67, 247, 249, 252, 251, 253), 'shippings': res.partner(85262,), 'error': {}, 'checkout': {'city': u'citt\xe0 invisibile', 'name': u'aaa-pluto', 'zip': u'17325', 'shipping_name': u'via Pisa', 'shipping_state_id': 15, 'street2': u'via questa', 'shipping_street': u'via pisa', 'country_id': 235, 'shipping_id': 85262, 'phone': u'2', 'shipping_zip': u'17325', 'street': u'strada per fatturazione', 'shipping_country_id': 235, 'state_id': 15, 'email': u'pluto@doglover.com', 'vat': u'', 'shipping_city': u'livorno'}}

2019-05-30 09:00:26,836 11905 DEBUG retail openerp.addons.website_sale.controllers.main:

 PARTNER SHIPPING ID [fine] CONFIRM ORDER >>> :: :: 85261

Body:
Add loop "for record_or_somthing in self: " before your condition and replace self in condition by "record_or_somthing".

for exemple :

         for record in self:
            if record.invoice_count >= 1:
                record.client_actif = True

            else:
                record.client_actif = False


问:
select from string from outcome of json file in postgresql
In postgre sql my table has attributes column with json format below

```<code>{"color": true,"view": [184],"school":
[805,812,855,856,857]}
</code>```

I would like write a column that if the school contains 805,812,855 then 1 else 0. Below I tried but it is not working.

```<code> case when  json_extract_path_text(attributes, 'school') in
 [805,812,855] then 1 else 0 end as school
</code>```

How can I fix this?
Thank you.

答:
You can use a lateral cross join to create an array for each row and see if it contains the values in [805,812,855].  Here, I'm assuming you want to make sure it contains ALL the values, not ANY of the values.</p>

```<code>with data as (select * from (values
  ('{"color": true,"view": [184],"school":[805,812,855,856,857]}'::jsonb),
  ('{"color": true,"view": [184],"school":[805,812]}'::jsonb)
) as v(data))
SELECT school_arr @> '{805,812,855}'
FROM data
CROSS JOIN LATERAL (SELECT ARRAY(SELECT jsonb_array_elements_text(data -> 'school'))) d(school_arr)
;
 ?column?
----------
 t
 f
(2 rows)
</code>```

Body:
In postgre sql my table has attributes column with json format below

{"color": true,"view": [184],"school":
[805,812,855,856,857]}

I would like write a column that if the school contains 805,812,855 then 1 else 0. Below I tried but it is not working.

 case when  json_extract_path_text(attributes, 'school') in
 [805,812,855] then 1 else 0 end as school

How can I fix this?
Thank you.

Body:
You can use a lateral cross join to create an array for each row and see if it contains the values in [805,812,855].  Here, I'm assuming you want to make sure it contains ALL the values, not ANY of the values.

with data as (select * from (values
  ('{"color": true,"view": [184],"school":[805,812,855,856,857]}'::jsonb),
  ('{"color": true,"view": [184],"school":[805,812]}'::jsonb)
) as v(data))
SELECT school_arr @> '{805,812,855}'
FROM data
CROSS JOIN LATERAL (SELECT ARRAY(SELECT jsonb_array_elements_text(data -> 'school'))) d(school_arr)
;
 ?column?
----------
 t
 f
(2 rows)


问:
How can I pass a URL querystring variable dynamically to a composed graphql query in react?
I am attempting to build a component using date from a graphql query but cannot see how dynamically supply a variable if it is not available in props when my component is created. eg. I have:-

```<code>class UsageComponent extends Component {
    render() {
        const params = this.queryStringParse(window.location.href);
        const queryStringImageId = params.id;

        const imageDetailsResults = this.props.getImageDetails.imageByImageId

        (etc...)
    }
}

const GET_IMAGE_DETAILS_QUERY = gql`
    query getImageDetails($imageId: Int!){
        imageByImageId(imageId:$imageId) {
            filename
            originalFilename
            width
            height
            description
            (etc...)
        }
    }
`;

export default compose(
        graphql(GET_IMAGE_DETAILS_QUERY, {name: "getImageDetails", options: props => { return { variables: { imageId: 123456 }}; }}),
        graphql(GET_PUBLICATIONS_QUERY, {name: "getPublications"})
)(ImageBrowser);
</code>```

Which works fine. i.e. imageDetailsResults is populated and I can use the data subsequently in the render function.

However I would like to be able to replace that hard set "imageId: 123456" in the composed graphql with the queryStringImageId value I get in the component render.

I don't think I am able to set this a props value as I'm coming to this component page from a redirected url:-

```<code><Switch>
    <AuthRoute path="/image" component={ImageBrowser} token={token} />
</Switch>
</code>```

Any suggestions would be much appreciated!

答:
You're probably looking for a method to use urls like /image/123456.

With react-router-dom you can define route with param:

```<code>    <AuthRoute path="/image/:id" component={ImageBrowser} token={token} />
</code>```

This way component gets router's prop passed in, match.params.id in this case ... and we're only one step away from final param passing:

```<code>export default compose(
    graphql(GET_IMAGE_DETAILS_QUERY, {
      name: "getImageDetails",
      options: props => {
        return { variables: { imageId: props.match.params.id }};
      }}),
    graphql(GET_PUBLICATIONS_QUERY, {name: "getPublications"})
)(ImageBrowser);
</code>```

Body:
I am attempting to build a component using date from a graphql query but cannot see how dynamically supply a variable if it is not available in props when my component is created. eg. I have:-

class UsageComponent extends Component {
    render() {
        const params = this.queryStringParse(window.location.href);
        const queryStringImageId = params.id;

        const imageDetailsResults = this.props.getImageDetails.imageByImageId

        (etc...)
    }
}

const GET_IMAGE_DETAILS_QUERY = gql`
    query getImageDetails($imageId: Int!){
        imageByImageId(imageId:$imageId) {
            filename
            originalFilename
            width
            height
            description
            (etc...)
        }
    }
`;

export default compose(
        graphql(GET_IMAGE_DETAILS_QUERY, {name: "getImageDetails", options: props => { return { variables: { imageId: 123456 }}; }}),
        graphql(GET_PUBLICATIONS_QUERY, {name: "getPublications"})
)(ImageBrowser);

Which works fine. i.e. imageDetailsResults is populated and I can use the data subsequently in the render function.

However I would like to be able to replace that hard set "imageId: 123456" in the composed graphql with the queryStringImageId value I get in the component render.

I don't think I am able to set this a props value as I'm coming to this component page from a redirected url:-

<Switch>
    <AuthRoute path="/image" component={ImageBrowser} token={token} />
</Switch>

Any suggestions would be much appreciated!

Body:
You're probably looking for a method to use urls like /image/123456.

With react-router-dom you can define route with param:

    <AuthRoute path="/image/:id" component={ImageBrowser} token={token} />

This way component gets router's prop passed in, match.params.id in this case ... and we're only one step away from final param passing:

export default compose(
    graphql(GET_IMAGE_DETAILS_QUERY, {
      name: "getImageDetails",
      options: props => {
        return { variables: { imageId: props.match.params.id }};
      }}),
    graphql(GET_PUBLICATIONS_QUERY, {name: "getPublications"})
)(ImageBrowser);


问:
I have 2 loops and results is not good
I have 2 loops, but unfortunately it does not work as it should. I want to take the first specific cells every 50 rows and paste them into another tab every 31 rows. Unfortunately, as it is now, I copy only one data range and paste it into the second tab repeating 332 times. I know what it results from, but I have no idea how to write it differently.</p>

```<code>Sub makro3()

    Dim X As Integer, X_max As Integer

    X_max = 332

    Y_max = 10292

    For X = 0 To X_max Step 50

        Sheets("Arkusz1").Select
        Cells(14 + X, 3).Select
        ActiveCell.Range("A1:T31").Select
        Selection.Copy
        Sheets("dane").Select

        For Y = 0 To Y_max Step 31
            Cells(2 + Y, 7).Select
            Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
                :=False, Transpose:=False
        Next Y

    Next X

End Sub
</code>```

答:
Try this:</p>

```<code>Option Explicit

Sub makro3()

    Dim X As Long, Y As Long
    Dim X_max As Long: X_max = 332
    Dim Y_max As Long: Y_max = 10292

    For X = 0 To X_max Step 50

        ThisWorkbook.Sheets("Arkusz1").Cells(14 + X, 3).Copy

        With ThisWorkbook.Sheets("dane")

            For Y = 0 To Y_max Step 31
                .Cells(2 + Y, 7).PasteSpecial Paste:=xlPasteValues
            Next Y

        End With

    Next X

End Sub
</code>```

Title: I have 2 loops and results is not good

Body:
I have 2 loops, but unfortunately it does not work as it should. I want to take the first specific cells every 50 rows and paste them into another tab every 31 rows. Unfortunately, as it is now, I copy only one data range and paste it into the second tab repeating 332 times. I know what it results from, but I have no idea how to write it differently.

Sub makro3()

    Dim X As Integer, X_max As Integer

    X_max = 332

    Y_max = 10292

    For X = 0 To X_max Step 50

        Sheets("Arkusz1").Select
        Cells(14 + X, 3).Select
        ActiveCell.Range("A1:T31").Select
        Selection.Copy
        Sheets("dane").Select

        For Y = 0 To Y_max Step 31
            Cells(2 + Y, 7).Select
            Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
                :=False, Transpose:=False
        Next Y

    Next X

End Sub

Body:
Try this:

Option Explicit

Sub makro3()

    Dim X As Long, Y As Long
    Dim X_max As Long: X_max = 332
    Dim Y_max As Long: Y_max = 10292

    For X = 0 To X_max Step 50

        ThisWorkbook.Sheets("Arkusz1").Cells(14 + X, 3).Copy

        With ThisWorkbook.Sheets("dane")

            For Y = 0 To Y_max Step 31
                .Cells(2 + Y, 7).PasteSpecial Paste:=xlPasteValues
            Next Y

        End With

    Next X

End Sub


问:
Flask WTForms always give false on validate_on_submit()
I have created a signup form using wtforms. I am using FormField in it so that I don't have to repeat some of the elements of the form again. But whenever I click on the Submit button it always give me false on validate_on_submit method invocation. Not getting why is this happening.

My form.py is as follows:

```<code>class ProfileInfoForm(Form):
    firstname = TextField('firstname', validators=
                          [validators.Required("Please enter First name.")])
    lastname = TextField('lastname', validators=
                         [validators.Required("Please enter Last name.")])
    email = EmailField('email', validators=
                       [validators.Required("Please enter your valid email.")])
    gender = RadioField('gender', validators=
                        [validators.Required("Please select gender")],
                        choices=[('female', 'Female'), ('male', 'Male')])
    dob = TextField('dob', validators=
                    [validators.Required("Please select date of birth.")])
    languages = SelectMultipleField('languages', choices=[('', '')],
                                    validators=
                                    [validators.Required("Please select\
                                                         atleast one \
                                                         language.")])

class RegistrationForm(Form):
    profilefield = FormField(ProfileInfoForm)
    password = PasswordField('password',
                             validators=
                             [validators.Required("Please enter password."),
                              validators.Length(min=8),
                              validators.EqualTo('confirm_password',
                                                 message='Password and confirm\
                                                 password must match')])
    confirm_password = PasswordField('confirm_password',
                                     validators=
                                     [validators.Required("Please enter\
                                                          confirm password.")])
    tnc = BooleanField('tnc', validators=
                       [validators.Required("Please select Terms and \
                                            Conditions")], default=False)

    submit = SubmitField('Create My Account')
</code>```

Signup method is as follows:

```<code>@module.route('/signup', methods=['GET', 'POST'])
  @handle_error
  def signup():
      if hasattr(g, 'user') and g.user:
          # TODO: do some operations if needed else keep it blank
          return redirect(url_for('index'))
      else:
          signup_form = RegistrationForm()
          # Add choices for the user
          signup_form.profilefield.languages.choices = getLanguages()
          if signup_form.validate_on_submit():
              firstname = signup_form.profilefield.firstname.data
              lastname = signup_form.profilefield.lastname.data
              email = signup_form.profilefield.email.data
              password = signup_form.password.data
              #  confirm_password = signup_form.confirm_password.data
              gender = signup_form.profilefield.gender.data
              dob = signup_form.profilefield.dob.data
              languages = signup_form.profilefield.languages.data
              tnc = signup_form.tnc.data

              payload = {'firstname': firstname, 'lastname': lastname,
                         'email': email, 'password': password, 'gender': gender,
                         'dob': dob, 'languages': languages,
                         'tnc': ('1' if tnc else '0')}
              try:
                  buildApiUrl = BuildApiUrl()
                  response = requests.post(buildApiUrl.getUrl("user", "signup"),
                                           data=payload)

                  if response.status_code == requests.codes.ok:
                      data = json.loads(response.text)
                      if 'status' in data and data['status'] != 200:
                          flash(data['message'], category="error")
                      else:
                          flash(data['message'] +
                                ': Your account is created successfully! ' +
                                'Please login to your account!',
                                category="success")
                          return redirect(url_for('index'))
              except requests.exceptions.RequestException:
                  flash('Internal Server side error occured', category="error")
                  return redirect(url_for('server_error', e='500'))

      return render_template('public/index.html',
                             signup_form=signup_form, login_form=LoginForm())
</code>```

HTML form is present on gist here

FYI: I am putting all the required fields with actual data needed. Still getting false when I call validate_on_submit(). What is wrong in my code?

EDIT: getLanguages is a method that retrieves languages from database and put in select list. This functionality is happening as expected and I can get list of languages.

Edit 2: Realize one thing here. This is happening due to FormField, since I tested by adding all the fields of ProfileInfoForm() into RegistrationForm() method, and everything worked just fine and I could signup. So some issue with the FormField or the way I am using it, but not sure where it is going wrong.

Found out that the problem is not with FormField but with my ProfileInfoForm(). It returns false always. Not yet got reason but I think I may have to write my own validation for that matter. Any thoughts?

Edit:

On dump I got following (used pprint here):

```<code>{'SECRET_KEY': '1e4c35233e50840483467e8d6cfe556c',
 '_errors': None,
 '_fields': {'csrf_token': <wtforms.ext.csrf.fields.CSRFTokenField object at 0x2207290>,
             'dob': <wtforms.fields.simple.TextField object at 0x2207650>,
             'email': <flask_wtf.html5.EmailField object at 0x22074d0>,
             'firstname': <wtforms.fields.simple.TextField object at 0x2207350>,
             'gender': <wtforms.fields.core.RadioField object at 0x2207590>,
             'languages': <wtforms.fields.core.SelectMultipleField object at 0x2207710>,
             'lastname': <wtforms.fields.simple.TextField object at 0x2207410>},
 '_prefix': u'profilefield-',
 'csrf_enabled': True,
 'csrf_token': <wtforms.ext.csrf.fields.CSRFTokenField object at 0x2207290>,
 'dob': <wtforms.fields.simple.TextField object at 0x2207650>,
 'email': <flask_wtf.html5.EmailField object at 0x22074d0>,
 'firstname': <wtforms.fields.simple.TextField object at 0x2207350>,
 'gender': <wtforms.fields.core.RadioField object at 0x2207590>,
 'languages': <wtforms.fields.core.SelectMultipleField object at 0x2207710>,
 'lastname': <wtforms.fields.simple.TextField object at 0x2207410>}
</code>```

Edit:

I dig little bit and found that the error is generated is due to csrf token missing. But I have included  {{ signup_form.hidden_tag() }} in my form template in html. and I can see hidden tag in html generated when I do inspect element and can see csrf_token field with hash value. So what is wrong in here?

答:
I had the same issue and I was able to fix it.

The problem was related to the fact that the LoginForm had the id and username with a validators while the html form was not requiring the information

```<code>            <h1>Login</h1>

            <form action="" method="POST"  name="login">
        {{ login_form.csrf_token }}
        {{ login_form.hidden_tag() }}

        <p>
            {{ login_form.email.label }}<br>
            {{ login_form.email(size=64) }}<br>
            {% for error in login_form.email.errors %}
            <span style="color: red;">[{{ error }}]</span>
            {% endfor %}
        </p>
        <p>
            {{ login_form.password.label }}<br>
            {{ login_form.password(size=32) }}<br>
            {% for error in login_form.password.errors %}
            <span style="color: red;">[{{ error }}]</span>
            {% endfor %}
        </p>
        <p>{{ login_form.remember_me }} Remember Me</p>
{#            <input type="submit" value="Sign In">#}
        <p>{{ login_form.submit() }}</p>
    </form>

class LoginForm(FlaskForm):
    ***# user_id = StringField('user_id',validators=[DataRequired()])
    # user_name = StringField('user_name',validators=[DataRequired(), Length(min=3, max=20)])***
    email = StringField('Email', validators=[DataRequired(), Email()])
    password = PasswordField('Password', validators=[DataRequired()])
    remember_me = BooleanField('remember_me', default=False)
    submit = SubmitField('LogIn')
</code>```

Body:
I have created a signup form using wtforms. I am using FormField in it so that I don't have to repeat some of the elements of the form again. But whenever I click on the Submit button it always give me false on validate_on_submit method invocation. Not getting why is this happening.

My form.py is as follows:

class ProfileInfoForm(Form):
    firstname = TextField('firstname', validators=
                          [validators.Required("Please enter First name.")])
    lastname = TextField('lastname', validators=
                         [validators.Required("Please enter Last name.")])
    email = EmailField('email', validators=
                       [validators.Required("Please enter your valid email.")])
    gender = RadioField('gender', validators=
                        [validators.Required("Please select gender")],
                        choices=[('female', 'Female'), ('male', 'Male')])
    dob = TextField('dob', validators=
                    [validators.Required("Please select date of birth.")])
    languages = SelectMultipleField('languages', choices=[('', '')],
                                    validators=
                                    [validators.Required("Please select\
                                                         atleast one \
                                                         language.")])

class RegistrationForm(Form):
    profilefield = FormField(ProfileInfoForm)
    password = PasswordField('password',
                             validators=
                             [validators.Required("Please enter password."),
                              validators.Length(min=8),
                              validators.EqualTo('confirm_password',
                                                 message='Password and confirm\
                                                 password must match')])
    confirm_password = PasswordField('confirm_password',
                                     validators=
                                     [validators.Required("Please enter\
                                                          confirm password.")])
    tnc = BooleanField('tnc', validators=
                       [validators.Required("Please select Terms and \
                                            Conditions")], default=False)

    submit = SubmitField('Create My Account')

Signup method is as follows:

@module.route('/signup', methods=['GET', 'POST'])
  @handle_error
  def signup():
      if hasattr(g, 'user') and g.user:
          # TODO: do some operations if needed else keep it blank
          return redirect(url_for('index'))
      else:
          signup_form = RegistrationForm()
          # Add choices for the user
          signup_form.profilefield.languages.choices = getLanguages()
          if signup_form.validate_on_submit():
              firstname = signup_form.profilefield.firstname.data
              lastname = signup_form.profilefield.lastname.data
              email = signup_form.profilefield.email.data
              password = signup_form.password.data
              #  confirm_password = signup_form.confirm_password.data
              gender = signup_form.profilefield.gender.data
              dob = signup_form.profilefield.dob.data
              languages = signup_form.profilefield.languages.data
              tnc = signup_form.tnc.data

              payload = {'firstname': firstname, 'lastname': lastname,
                         'email': email, 'password': password, 'gender': gender,
                         'dob': dob, 'languages': languages,
                         'tnc': ('1' if tnc else '0')}
              try:
                  buildApiUrl = BuildApiUrl()
                  response = requests.post(buildApiUrl.getUrl("user", "signup"),
                                           data=payload)

                  if response.status_code == requests.codes.ok:
                      data = json.loads(response.text)
                      if 'status' in data and data['status'] != 200:
                          flash(data['message'], category="error")
                      else:
                          flash(data['message'] +
                                ': Your account is created successfully! ' +
                                'Please login to your account!',
                                category="success")
                          return redirect(url_for('index'))
              except requests.exceptions.RequestException:
                  flash('Internal Server side error occured', category="error")
                  return redirect(url_for('server_error', e='500'))

      return render_template('public/index.html',
                             signup_form=signup_form, login_form=LoginForm())

HTML form is present on gist here

FYI: I am putting all the required fields with actual data needed. Still getting false when I call validate_on_submit(). What is wrong in my code?

EDIT: getLanguages is a method that retrieves languages from database and put in select list. This functionality is happening as expected and I can get list of languages.

Edit 2: Realize one thing here. This is happening due to FormField, since I tested by adding all the fields of ProfileInfoForm() into RegistrationForm() method, and everything worked just fine and I could signup. So some issue with the FormField or the way I am using it, but not sure where it is going wrong.

Found out that the problem is not with FormField but with my ProfileInfoForm(). It returns false always. Not yet got reason but I think I may have to write my own validation for that matter. Any thoughts?

Edit:

On dump I got following (used pprint here):

{'SECRET_KEY': '1e4c35233e50840483467e8d6cfe556c',
 '_errors': None,
 '_fields': {'csrf_token': <wtforms.ext.csrf.fields.CSRFTokenField object at 0x2207290>,
             'dob': <wtforms.fields.simple.TextField object at 0x2207650>,
             'email': <flask_wtf.html5.EmailField object at 0x22074d0>,
             'firstname': <wtforms.fields.simple.TextField object at 0x2207350>,
             'gender': <wtforms.fields.core.RadioField object at 0x2207590>,
             'languages': <wtforms.fields.core.SelectMultipleField object at 0x2207710>,
             'lastname': <wtforms.fields.simple.TextField object at 0x2207410>},
 '_prefix': u'profilefield-',
 'csrf_enabled': True,
 'csrf_token': <wtforms.ext.csrf.fields.CSRFTokenField object at 0x2207290>,
 'dob': <wtforms.fields.simple.TextField object at 0x2207650>,
 'email': <flask_wtf.html5.EmailField object at 0x22074d0>,
 'firstname': <wtforms.fields.simple.TextField object at 0x2207350>,
 'gender': <wtforms.fields.core.RadioField object at 0x2207590>,
 'languages': <wtforms.fields.core.SelectMultipleField object at 0x2207710>,
 'lastname': <wtforms.fields.simple.TextField object at 0x2207410>}

Edit:

I dig little bit and found that the error is generated is due to csrf token missing. But I have included  {{ signup_form.hidden_tag() }} in my form template in html. and I can see hidden tag in html generated when I do inspect element and can see csrf_token field with hash value. So what is wrong in here?

Body:
I had the same issue and I was able to fix it.

The problem was related to the fact that the LoginForm had the id and username with a validators while the html form was not requiring the information

            <h1>Login</h1>

            <form action="" method="POST"  name="login">
        {{ login_form.csrf_token }}
        {{ login_form.hidden_tag() }}

        <p>
            {{ login_form.email.label }}<br>
            {{ login_form.email(size=64) }}<br>
            {% for error in login_form.email.errors %}
            <span style="color: red;">[{{ error }}]</span>
            {% endfor %}
        </p>
        <p>
            {{ login_form.password.label }}<br>
            {{ login_form.password(size=32) }}<br>
            {% for error in login_form.password.errors %}
            <span style="color: red;">[{{ error }}]</span>
            {% endfor %}
        </p>
        <p>{{ login_form.remember_me }} Remember Me</p>
{#            <input type="submit" value="Sign In">#}
        <p>{{ login_form.submit() }}</p>
    </form>

class LoginForm(FlaskForm):
    ***# user_id = StringField('user_id',validators=[DataRequired()])
    # user_name = StringField('user_name',validators=[DataRequired(), Length(min=3, max=20)])***
    email = StringField('Email', validators=[DataRequired(), Email()])
    password = PasswordField('Password', validators=[DataRequired()])
    remember_me = BooleanField('remember_me', default=False)
    submit = SubmitField('LogIn')


问:
Why JWT is considered as can't be managed from server?
I know perfectly what JWT is. But it is a known fact that there is a problem with revoking the JWT .

For example, I've read here:

We had several cases where we wanted the users at HelpTap to logout by
  cleaning up the cookies, but we cannot ask them to do so every time.
  As well consider the case that a user’s mobile is stolen, and he wants
  to logout of all existing sessions(e.g. Gmail’s logout other sessions
  feature). Well it's not possible in case of JWT.

But if I can store the user's info in the jwt data section, then I can also create a DB in the server which will check whether a specific user should be revoked or not.

If it should, then I can send a new JWT.

Question:

What am I missing? I sure can revoke the specific user's JWT and send him a new one.

答:
JWS (that is, a signed JWT) relies on a cryptographic signature to ensure the integrity of the claims, so many application developers tend to use it to provide stateless authentication: if the signature is valid and the token is not expired, then the token can be trusted without depending on any state stored on the server.

That's a great and powerful approach, but it comes with a trade-off: it doesn't give you much control when you need to manage token revocation. So it's not a one-size-fits-all approach: it may work well in some contexts (such as microservices identity propagation) but it may not be suitable for all applications.

If you need the ability to revoke tokens, then it comes with a cost: you need to keep the track of them somewhere in your server, either in a whitelist or in a blacklist.

To achieve it, you could assign a unique identifier to each token and then store such identifier in your server. When validating the token, besides checking the signature and the expiration date, you must also check whether the token identifier is whitelisted (or is not blacklisted).

Finally, the jti claim is meant for storing a unique identifier in the token:

4.1.7.  "jti" (JWT ID) Claim

The jti (JWT ID) claim provides a unique identifier for the JWT. The identifier value MUST be assigned in a manner that ensures that there is a negligible probability that the same value will be accidentally assigned to a different data object; if the application uses multiple issuers, collisions MUST be prevented among values produced by different issuers as well.  The jti claim can be used to prevent the JWT from being replayed.  The jti value is a case-sensitive string.  Use of this claim is OPTIONAL.


问:
How to set up local subdomains for Node.js app
I am running an express app on node.js. The app uses the express-subdomain module to help handle routes for two different subdomains (sub1.example.com and sub2.example.com). I'm hosting the app on AWS Elastic Beanstalk. In my production environment, everything works great. But on my local machine, I cannot get this to work. I tried adding the subdomains to my host file 127.0.0.1 localhost sub1.localhost sub2.localhost. Although that allows me to prepend a subdomain to localhost, the module doesn't recognize this as a valid subdomain, and therefor searches for subdomain routes in my root routes.

In main.js:

```<code>var routes = require('./routes/index')(passport);
var sub1_routes = require('./routes/sub1')(passport);
var sub2_routes = require('./routes/sub2')(passport);

app.use(subdomain('sub1', sub1_routes));
app.use(subdomain('sub2', sub1_routes));
app.use('/', routes);
</code>```

I need to be able to handle this locally. It takes to much time to push a small change to AWS test, iterate, etc.

答:
There is an awesome website, which someone hosted for all of us.

localtest.me

All requests will be routed to 127.0.0.1, including subdomains.
e.g something.localtest.me:3000
will resolve to 127.0.0.1:3000

but, for example, in your Express app, if you do

```<code> app.get('*', (req, res) => {
     console.log(req.subdomains); // [ something ]
 });

</code>```

you'll get your subdomain

Body:
I am running an express app on node.js. The app uses the express-subdomain module to help handle routes for two different subdomains (sub1.example.com and sub2.example.com). I'm hosting the app on AWS Elastic Beanstalk. In my production environment, everything works great. But on my local machine, I cannot get this to work. I tried adding the subdomains to my host file 127.0.0.1 localhost sub1.localhost sub2.localhost. Although that allows me to prepend a subdomain to localhost, the module doesn't recognize this as a valid subdomain, and therefor searches for subdomain routes in my root routes.

In main.js:

var routes = require('./routes/index')(passport);
var sub1_routes = require('./routes/sub1')(passport);
var sub2_routes = require('./routes/sub2')(passport);

app.use(subdomain('sub1', sub1_routes));
app.use(subdomain('sub2', sub1_routes));
app.use('/', routes);

I need to be able to handle this locally. It takes to much time to push a small change to AWS test, iterate, etc.

Body:
There is an awesome website, which someone hosted for all of us.

localtest.me

All requests will be routed to 127.0.0.1, including subdomains.
e.g something.localtest.me:3000
will resolve to 127.0.0.1:3000

but, for example, in your Express app, if you do

 app.get('*', (req, res) => {
     console.log(req.subdomains); // [ something ]
 });

you'll get your subdomain