问:
Ceylon module system: Guava class mismatch even though there's only one Guava in dependencies tree
I'm defining an adapter for JSimpleDB (a persistence library) by subclassing a class that takes a Google Guava Converter as constructor parameter:

```<code>shared class RoleConverter() extends Converter<Role, String>() {
    shared actual Role doBackward(String? name) {
        "Cannot convert null to role."
        assert (exists name);
        return Role.ofName(name);
    }

    shared actual String doForward(Role? role) {
        return role?.name else "null";
    }
}

shared class RoleType() extends StringEncodedType<Role>(
    javaClass<Role>(),
    0,
    RoleConverter()
) {
}
</code>```

JSimpleDB doesn't export Guava by default, so I added the following overrides.xml to make sure the correct classes are visible to my application (I'm not using --auto-export-maven-depencies or --flat-classpath):

```<code><overrides xmlns="http://www.ceylon-lang.org/xsd/overrides">
    <module groupId="org.jsimpledb" artifactId="jsimpledb-coreapi">
        <share groupId="com.google.guava" artifactId="guava" />
    </module>
    <module groupId="org.jsimpledb" artifactId="jsimpledb-main">
        <!-- guava is already shared by jsimpledb-coreapi -->
        <remove groupId="com.google.guava" artifactId="guava" />
        <share groupId="org.jsimpledb" artifactId="jsimpledb-coreapi" />
        <share groupId="org.jsimpledb" artifactId="jsimpledb-util" />
        <share groupId="org.dellroad" artifactId="dellroad-stuff-main" />
    </module>
</overrides>
</code>```

This results in the following module hierarchy (my code is in fun.uschool.user.impl):

The correct com.google.guava:guava module should be exposed to my program, and indeed I can import Converter, but when I try to compile the above code I get the following error:

```<code>source/fun/uschool/user/impl/userImpl.ceylon:156: error: argument must be assignable to parameter 'arg2' of 'StringEncodedType': 'RoleConverter' is not assignable to 'Converter<Role,String>?'
    RoleConverter()
    ^
source/fun/uschool/user/impl/userImpl.ceylon:153: error: Ceylon backend error: no suitable constructor found for StringEncodedType(no arguments)
shared class RoleType() extends StringEncodedType<Role>(
^
    constructor StringEncodedType.StringEncodedType(Class<Role>,long,Converter<Role,String>) is not applicable
      (actual and formal argument lists differ in length)
    constructor StringEncodedType.StringEncodedType(String,Class<Role>,long,Converter<Role,String>) is not applicable
      (actual and formal argument lists differ in length)
Note: Created module fun.uschool.feature.spi/1.0.0
Note: Created module fun.uschool.user.api/1.0.0
Note: Created module fun.uschool.feature.impl/1.0.0
Note: Created module fun.uschool.user.impl/1.0.0
ceylon compile: There were 2 errors
</code>```

So apparently somehow the wrong com.google.guava:guava imported, even though there's only 1 visible in the module dependencies tree. How do I import the right one?

Here's the output of ceylon info's dependency analysis:

```<code>$ ceylon info fun.uschool.user.impl/1.0.0 --dependency-depth=all
Namespace:   ceylon
Name:        fun.uschool.user.impl
Version:     1.0.0
Artifacts:   JVM (#8.1), Sources
Available:   On local system
Origin:      /home/ilmoeuro/Asiakirjat/Projektit/youschool/modules
Dependency Tree (up to depth ∞):
  ceylon.buffer/1.3.2
      ceylon.collection/1.3.2
          ceylon.language/1.3.2
      ceylon.interop.java/1.3.2
          shared ceylon.collection/1.3.2 (already imported)
          ceylon.language/1.3.2 (already imported)
          shared java.base/7
      ceylon.language/1.3.2 (already imported)
      java.base/7 (already imported)
  ceylon.interop.java/1.3.2 (already imported)
  ceylon.language/1.3.2 (already imported)
  ceylon.test/1.3.2
      ceylon.collection/1.3.2 (already imported)
      ceylon.file/1.3.2
          ceylon.language/1.3.2 (already imported)
          java.base/7 (already imported)
      ceylon.language/1.3.2 (already imported)
      ceylon.runtime/1.3.2
          shared ceylon.language/1.3.2 (already imported)
          shared com.redhat.ceylon.cli/1.3.2
              shared com.redhat.ceylon.common/1.3.2
                  shared java.base/7 (already imported)
                  java.desktop/7
                  shared java.logging/7
              shared com.redhat.ceylon.module-resolver/1.3.2
                  shared com.redhat.ceylon.common/1.3.2 (already imported)
                  shared com.redhat.ceylon.langtools.classfile/1.3.2
                      shared java.base/7 (already imported)
                  shared com.redhat.ceylon.model/1.3.2
                      shared com.redhat.ceylon.common/1.3.2 (already imported)
                      shared com.redhat.ceylon.langtools.classfile/1.3.2 (already imported)
                      shared java.base/7 (already imported)
                      shared java.logging/7 (already imported)
                  optional com.redhat.ceylon.module-resolver-aether/1.3.2
                  optional com.redhat.ceylon.module-resolver-javascript/1.3.2
                  optional com.redhat.ceylon.module-resolver-webdav/1.3.2
                  shared java.base/7 (already imported)
                  shared java.logging/7 (already imported)
                  javax.jaxws/7
                  javax.script/7
                  shared javax.xml/7
              shared java.base/7 (already imported)
              java.desktop/7 (already imported)
              shared java.logging/7 (already imported)
              shared optional org.tautua.markdownpapers.core/1.2.7
          shared com.redhat.ceylon.common/1.3.2 (already imported)
          shared com.redhat.ceylon.model/1.3.2 (already imported)
          shared com.redhat.ceylon.module-resolver/1.3.2 (already imported)
          com.redhat.ceylon.tool.provider/1.3.2
              ceylon.language/1.3.2 (already imported)
              shared com.redhat.ceylon.cli/1.3.2 (already imported)
              shared com.redhat.ceylon.common/1.3.2 (already imported)
              shared com.redhat.ceylon.compiler.java/1.3.2
                  ceylon.language/1.3.2 (already imported)
                  com.github.rjeschke.txtmark/0.13
                      shared java.base/7 (already imported)
                  shared com.redhat.ceylon.cli/1.3.2 (already imported)
                  shared com.redhat.ceylon.common/1.3.2 (already imported)
                  shared com.redhat.ceylon.langtools.classfile/1.3.2 (already imported)
                  shared com.redhat.ceylon.model/1.3.2 (already imported)
                  shared com.redhat.ceylon.module-resolver/1.3.2 (already imported)
                  shared com.redhat.ceylon.typechecker/1.3.2
                      shared com.redhat.ceylon.common/1.3.2 (already imported)
                      shared com.redhat.ceylon.model/1.3.2 (already imported)
                      shared com.redhat.ceylon.module-resolver/1.3.2 (already imported)
                      shared java.base/7 (already imported)
                      shared org.antlr.runtime/3.4
                          shared java.base/7 (already imported)
                          shared org.antlr.stringtemplate/3.2.1
                              shared java.base/7 (already imported)
                              shared java.desktop/7 (already imported)
                              shared org.antlr.antlr/2.7.7
                                  shared java.base/7 (already imported)
                                  shared java.desktop/7 (already imported)
                  shared java.base/7 (already imported)
                  shared java.compiler/7
                  java.desktop/7 (already imported)
                  java.logging/7 (already imported)
                  java.prefs/7
                  shared javax.xml/7 (already imported)
                  oracle.jdk.base/7
                  shared org.antlr.runtime/3.4 (already imported)
              com.redhat.ceylon.compiler.js/1.3.2
                  ceylon.language/1.3.2 (already imported)
                  shared com.redhat.ceylon.cli/1.3.2 (already imported)
                  shared com.redhat.ceylon.common/1.3.2 (already imported)
                  shared com.redhat.ceylon.model/1.3.2 (already imported)
                  shared com.redhat.ceylon.module-resolver/1.3.2 (already imported)
                  com.redhat.ceylon.module-resolver-javascript/1.3.2
                      net.minidev.json-smart/1.1.1
                          shared java.base/7 (already imported)
                  shared com.redhat.ceylon.typechecker/1.3.2 (already imported)
                  shared java.base/7 (already imported)
                  shared java.logging/7 (already imported)
                  net.minidev.json-smart/1.1.1 (already imported)
                  shared org.antlr.runtime/3.4 (already imported)
              com.redhat.ceylon.model/1.3.2 (already imported)
              com.redhat.ceylon.module-loader/1.3.2
                  ceylon.language/1.3.2 (already imported)
                  com.redhat.ceylon.common/1.3.2 (already imported)
                  com.redhat.ceylon.model/1.3.2 (already imported)
                  shared com.redhat.ceylon.module-resolver/1.3.2 (already imported)
                  shared java.base/7 (already imported)
                  optional org.jboss.modules/1.4.4.Final
              shared com.redhat.ceylon.module-resolver/1.3.2 (already imported)
              com.redhat.ceylon.typechecker/1.3.2 (already imported)
              shared java.base/7 (already imported)
              org.jboss.modules/1.4.4.Final
                  shared java.base/7 (already imported)
                  shared java.instrument/7
                  shared java.logging/7 (already imported)
                  java.management/7
                  java.prefs/7 (already imported)
                  shared javax.xml/7 (already imported)
                  oracle.jdk.base/7 (already imported)
          shared java.base/7 (already imported)
          java.compiler/7 (already imported)
          shared java.instrument/7 (already imported)
          javax.xml/7 (already imported)
          org.jboss.logmanager/2.0.3.Final
              shared java.base/7 (already imported)
              shared java.logging/7 (already imported)
              java.management/7 (already imported)
              shared java.tls/7
              optional org.jboss.modules/1.4.4.Final
          shared org.jboss.modules/1.4.4.Final (already imported)
      java.base/7 (already imported)
      org.jboss.modules/1.4.4.Final (already imported)
  shared fun.uschool.feature.impl/1.0.0
      ceylon.buffer/1.3.2 (already imported)
      ceylon.interop.java/1.3.2 (already imported)
      ceylon.language/1.3.2 (already imported)
      shared maven:com.moandjiezana.toml:toml4j/0.7.1
          maven:com.google.code.gson:gson/2.3.1
      shared fun.uschool.feature.spi/1.0.0
          ceylon.language/1.3.2 (already imported)
      shared java.base/8 (already imported other version)
      shared maven:org.jsimpledb:jsimpledb-main/3.5.0
          maven:com.google.code.findbugs:jsr305/3.0.1 PROVIDED
          maven:javax.el:javax.el-api/2.2.5
          maven:javax.validation:validation-api/1.1.0.Final
          maven:log4j:log4j/1.2.17 RUNTIME
              optional maven:javax.mail:mail/1.4.3
              optional maven:org.apache.geronimo.specs:geronimo-jms_1.1_spec/1.0
              maven:org.apache.openejb:javaee-api/5.0-2 PROVIDED
          maven:org.dellroad:dellroad-stuff-main/2.1.0
              optional maven:au.com.bytecode:opencsv/2.4
              maven:com.google.guava:guava/21.0
                  optional maven:com.google.code.findbugs:jsr305/1.3.9
                  optional maven:com.google.errorprone:error_prone_annotations/2.0.15
                  optional maven:com.google.j2objc:j2objc-annotations/1.1
                  optional maven:org.codehaus.mojo:animal-sniffer-annotations/1.14
              maven:javax.validation:validation-api/1.1.0.Final (already imported)
              optional maven:jline:jline/2.14.2
              optional maven:log4j:log4j/1.2.17
              optional maven:org.apache.ant:ant/1.9.7
              optional maven:org.hibernate.javax.persistence:hibernate-jpa-2.1-api/1.0.0.Final
              optional maven:org.hibernate:hibernate-core/5.0.7.Final
              maven:org.slf4j:slf4j-api/1.7.25
              maven:org.slf4j:slf4j-log4j12/1.7.25 RUNTIME
                  maven:log4j:log4j/1.2.17 (already imported)
                  maven:org.slf4j:slf4j-api/1.7.25 (already imported)
              optional maven:org.springframework:spring-context/4.3.7.RELEASE
          maven:org.hibernate:hibernate-validator/5.2.4.Final
              maven:com.fasterxml:classmate/1.1.0
              optional maven:com.thoughtworks.paranamer:paranamer/2.5.5
              maven:javax.el:javax.el-api/2.2.4 PROVIDED (already imported other version)
              maven:javax.validation:validation-api/1.1.0.Final (already imported)
              optional maven:joda-time:joda-time/2.7
              maven:org.glassfish.web:javax.el/2.2.4 PROVIDED
                  maven:javax.el:javax.el-api/2.2.4 (already imported other version)
              optional maven:org.hibernate.javax.persistence:hibernate-jpa-2.1-api/1.0.0.Final
              maven:org.jboss.logging:jboss-logging/3.2.1.Final
                  maven:log4j:log4j/1.2.16 PROVIDED (already imported other version)
                  maven:org.apache.logging.log4j:log4j-api/2.0 PROVIDED
                      maven:org.osgi:org.osgi.core/4.3.1 PROVIDED
                  maven:org.jboss.logmanager:jboss-logmanager/1.5.2.Final PROVIDED
                      optional maven:org.jboss.modules:jboss-modules/1.1.0.GA PROVIDED
                  maven:org.slf4j:slf4j-api/1.7.2 PROVIDED (already imported other version)
              maven:org.jboss.logging:jboss-logging-processor/1.2.0.Final PROVIDED
                  maven:org.jboss.jdeparser:jdeparser/1.0.0.Final
                  maven:org.jboss.logging:jboss-logging/3.1.2.GA PROVIDED (already imported other version)
                  maven:org.jboss.logging:jboss-logging-annotations/1.2.0.Final
                      maven:org.jboss.logging:jboss-logging/3.1.2.GA PROVIDED (already imported other version)
              optional maven:org.jsoup:jsoup/1.8.3
          shared maven:org.jsimpledb:jsimpledb-coreapi/3.5.0
              maven:com.google.code.findbugs:jsr305/3.0.1 PROVIDED (already imported)
              maven:commons-codec:commons-codec/1.10
              maven:log4j:log4j/1.2.17 RUNTIME (already imported other version)
              maven:org.dellroad:dellroad-stuff-main/2.1.0 (already imported)
              maven:org.jsimpledb:jsimpledb-kv/3.5.0
                  maven:com.google.code.findbugs:jsr305/3.0.1 PROVIDED (already imported)
                  maven:com.google.guava:guava/21.0 (already imported)
                  maven:log4j:log4j/1.2.17 RUNTIME (already imported other version)
                  maven:org.dellroad:dellroad-stuff-main/2.1.0 (already imported)
                  maven:org.jsimpledb:jsimpledb-util/3.5.0
                      maven:com.google.code.findbugs:jsr305/3.0.1 PROVIDED (already imported)
                      shared maven:com.google.guava:guava/21.0 (already imported)
                      maven:log4j:log4j/1.2.17 RUNTIME (already imported other version)
                      maven:org.slf4j:slf4j-api/1.7.25 (already imported other version)
                      maven:org.slf4j:slf4j-log4j12/1.7.25 RUNTIME (already imported)
                  maven:org.slf4j:slf4j-api/1.7.25 (already imported other version)
                  maven:org.slf4j:slf4j-log4j12/1.7.25 RUNTIME (already imported)
              shared maven:org.jsimpledb:jsimpledb-util/3.5.0 (already imported)
              maven:org.slf4j:slf4j-api/1.7.25 (already imported other version)
              maven:org.slf4j:slf4j-log4j12/1.7.25 RUNTIME (already imported)
          maven:org.jsimpledb:jsimpledb-kv/3.5.0 (already imported)
          maven:org.jsimpledb:jsimpledb-kv-simple/3.5.0
              maven:com.google.code.findbugs:jsr305/3.0.1 PROVIDED (already imported)
              maven:com.google.guava:guava/21.0 (already imported)
              maven:log4j:log4j/1.2.17 RUNTIME (already imported other version)
              maven:org.dellroad:dellroad-stuff-main/2.1.0 (already imported)
              maven:org.jsimpledb:jsimpledb-kv/3.5.0 (already imported)
              maven:org.jsimpledb:jsimpledb-util/3.5.0 (already imported)
              maven:org.slf4j:slf4j-api/1.7.25 (already imported other version)
              maven:org.slf4j:slf4j-log4j12/1.7.25 RUNTIME (already imported)
          maven:org.slf4j:slf4j-api/1.7.25 (already imported other version)
          maven:org.slf4j:slf4j-log4j12/1.7.25 RUNTIME (already imported)
  shared fun.uschool.feature.spi/1.0.0 (already imported)
  shared fun.uschool.user.api/1.0.0
      ceylon.language/1.3.2 (already imported)
      shared fun.uschool.feature.spi/1.0.0 (already imported)
      fun.uschool.user.impl/1.0.0
          ceylon.buffer/1.3.2 (already imported)
          ceylon.interop.java/1.3.2 (already imported)
          ceylon.language/1.3.2 (already imported)
          ceylon.test/1.3.2 (already imported)
          shared fun.uschool.feature.impl/1.0.0 (already imported)
          shared fun.uschool.feature.spi/1.0.0 (already imported)
          shared fun.uschool.user.api/1.0.0 (already imported)
          shared java.base/8 (already imported other version)
  shared java.base/8 (already imported other version)

Dependencies (up to depth ∞):
  ceylon.buffer/1.3.2
  ceylon.collection/1.3.2
  ceylon.file/1.3.2
  ceylon.interop.java/1.3.2
  ceylon.language/1.3.2
  ceylon.runtime/1.3.2
  ceylon.test/1.3.2
  com.fasterxml:classmate/1.1.0
  com.github.rjeschke.txtmark/0.13
  com.google.code.findbugs:jsr305/3.0.1
  com.google.code.gson:gson/2.3.1
  com.google.guava:guava/21.0
  com.moandjiezana.toml:toml4j/0.7.1
  com.redhat.ceylon.cli/1.3.2
  com.redhat.ceylon.common/1.3.2
  com.redhat.ceylon.compiler.java/1.3.2
  com.redhat.ceylon.compiler.js/1.3.2
  com.redhat.ceylon.langtools.classfile/1.3.2
  com.redhat.ceylon.model/1.3.2
  com.redhat.ceylon.module-loader/1.3.2
  com.redhat.ceylon.module-resolver/1.3.2
  com.redhat.ceylon.module-resolver-javascript/1.3.2
  com.redhat.ceylon.tool.provider/1.3.2
  com.redhat.ceylon.typechecker/1.3.2
  commons-codec:commons-codec/1.10
  fun.uschool.feature.impl/1.0.0
  fun.uschool.feature.spi/1.0.0
  fun.uschool.user.api/1.0.0
  fun.uschool.user.impl/1.0.0
  java.base: 7, 8
  java.compiler/7
  java.desktop/7
  java.instrument/7
  java.logging/7
  java.management/7
  java.prefs/7
  java.tls/7
  javax.el:javax.el-api: 2.2.4, 2.2.5
  javax.jaxws/7
  javax.script/7
  javax.validation:validation-api/1.1.0.Final
  javax.xml/7
  log4j:log4j: 1.2.16, 1.2.17
  net.minidev.json-smart/1.1.1
  oracle.jdk.base/7
  org.antlr.antlr/2.7.7
  org.antlr.runtime/3.4
  org.antlr.stringtemplate/3.2.1
  org.apache.logging.log4j:log4j-api/2.0
  org.apache.openejb:javaee-api/5.0-2
  org.dellroad:dellroad-stuff-main/2.1.0
  org.glassfish.web:javax.el/2.2.4
  org.hibernate:hibernate-validator/5.2.4.Final
  org.jboss.jdeparser:jdeparser/1.0.0.Final
  org.jboss.logging:jboss-logging: 3.1.2.GA, 3.2.1.Final
  org.jboss.logging:jboss-logging-annotations/1.2.0.Final
  org.jboss.logging:jboss-logging-processor/1.2.0.Final
  org.jboss.logmanager/2.0.3.Final
  org.jboss.logmanager:jboss-logmanager/1.5.2.Final
  org.jboss.modules/1.4.4.Final
  org.jsimpledb:jsimpledb-coreapi/3.5.0
  org.jsimpledb:jsimpledb-kv/3.5.0
  org.jsimpledb:jsimpledb-kv-simple/3.5.0
  org.jsimpledb:jsimpledb-main/3.5.0
  org.jsimpledb:jsimpledb-util/3.5.0
  org.osgi:org.osgi.core/4.3.1
  org.slf4j:slf4j-api: 1.7.2, 1.7.25
  org.slf4j:slf4j-log4j12/1.7.25

Dependencies version conflicts (up to depth ∞):
  java.base: 7, 8
  javax.el:javax.el-api: 2.2.4, 2.2.5
  log4j:log4j: 1.2.16, 1.2.17
  org.jboss.logging:jboss-logging: 3.1.2.GA, 3.2.1.Final
  org.slf4j:slf4j-api: 1.7.2, 1.7.25
</code>```

答:
Okay, I got it. The problem was that RoleConverter converts to ceylon.language.String, while the api was expecting a converter to java.lang.String. Fixed it now:

```<code>shared class RoleConverter() extends Converter<Role, JString>() {
    shared actual Role doBackward(JString? name) {
        "Cannot convert null to role."
        assert (exists name);
        return Role.ofName(name.string);
    }

    shared actual JString doForward(Role? role) {
        return JString(role?.name else "null");
    }
}
</code>```

Body:
I'm defining an adapter for JSimpleDB (a persistence library) by subclassing a class that takes a Google Guava Converter as constructor parameter:

shared class RoleConverter() extends Converter<Role, String>() {
    shared actual Role doBackward(String? name) {
        "Cannot convert null to role."
        assert (exists name);
        return Role.ofName(name);
    }

    shared actual String doForward(Role? role) {
        return role?.name else "null";
    }
}

shared class RoleType() extends StringEncodedType<Role>(
    javaClass<Role>(),
    0,
    RoleConverter()
) {
}

JSimpleDB doesn't export Guava by default, so I added the following overrides.xml to make sure the correct classes are visible to my application (I'm not using --auto-export-maven-depencies or --flat-classpath):

<overrides xmlns="http://www.ceylon-lang.org/xsd/overrides">
    <module groupId="org.jsimpledb" artifactId="jsimpledb-coreapi">
        <share groupId="com.google.guava" artifactId="guava" />
    </module>
    <module groupId="org.jsimpledb" artifactId="jsimpledb-main">

        <remove groupId="com.google.guava" artifactId="guava" />
        <share groupId="org.jsimpledb" artifactId="jsimpledb-coreapi" />
        <share groupId="org.jsimpledb" artifactId="jsimpledb-util" />
        <share groupId="org.dellroad" artifactId="dellroad-stuff-main" />
    </module>
</overrides>

This results in the following module hierarchy (my code is in fun.uschool.user.impl):

The correct com.google.guava:guava module should be exposed to my program, and indeed I can import Converter, but when I try to compile the above code I get the following error:

source/fun/uschool/user/impl/userImpl.ceylon:156: error: argument must be assignable to parameter 'arg2' of 'StringEncodedType': 'RoleConverter' is not assignable to 'Converter<Role,String>?'
    RoleConverter()
    ^
source/fun/uschool/user/impl/userImpl.ceylon:153: error: Ceylon backend error: no suitable constructor found for StringEncodedType(no arguments)
shared class RoleType() extends StringEncodedType<Role>(
^
    constructor StringEncodedType.StringEncodedType(Class<Role>,long,Converter<Role,String>) is not applicable
      (actual and formal argument lists differ in length)
    constructor StringEncodedType.StringEncodedType(String,Class<Role>,long,Converter<Role,String>) is not applicable
      (actual and formal argument lists differ in length)
Note: Created module fun.uschool.feature.spi/1.0.0
Note: Created module fun.uschool.user.api/1.0.0
Note: Created module fun.uschool.feature.impl/1.0.0
Note: Created module fun.uschool.user.impl/1.0.0
ceylon compile: There were 2 errors

So apparently somehow the wrong com.google.guava:guava imported, even though there's only 1 visible in the module dependencies tree. How do I import the right one?

Here's the output of ceylon info's dependency analysis:

$ ceylon info fun.uschool.user.impl/1.0.0 --dependency-depth=all
Namespace:   ceylon
Name:        fun.uschool.user.impl
Version:     1.0.0
Artifacts:   JVM (#8.1), Sources
Available:   On local system
Origin:      /home/ilmoeuro/Asiakirjat/Projektit/youschool/modules
Dependency Tree (up to depth ∞):
  ceylon.buffer/1.3.2
      ceylon.collection/1.3.2
          ceylon.language/1.3.2
      ceylon.interop.java/1.3.2
          shared ceylon.collection/1.3.2 (already imported)
          ceylon.language/1.3.2 (already imported)
          shared java.base/7
      ceylon.language/1.3.2 (already imported)
      java.base/7 (already imported)
  ceylon.interop.java/1.3.2 (already imported)
  ceylon.language/1.3.2 (already imported)
  ceylon.test/1.3.2
      ceylon.collection/1.3.2 (already imported)
      ceylon.file/1.3.2
          ceylon.language/1.3.2 (already imported)
          java.base/7 (already imported)
      ceylon.language/1.3.2 (already imported)
      ceylon.runtime/1.3.2
          shared ceylon.language/1.3.2 (already imported)
          shared com.redhat.ceylon.cli/1.3.2
              shared com.redhat.ceylon.common/1.3.2
                  shared java.base/7 (already imported)
                  java.desktop/7
                  shared java.logging/7
              shared com.redhat.ceylon.module-resolver/1.3.2
                  shared com.redhat.ceylon.common/1.3.2 (already imported)
                  shared com.redhat.ceylon.langtools.classfile/1.3.2
                      shared java.base/7 (already imported)
                  shared com.redhat.ceylon.model/1.3.2
                      shared com.redhat.ceylon.common/1.3.2 (already imported)
                      shared com.redhat.ceylon.langtools.classfile/1.3.2 (already imported)
                      shared java.base/7 (already imported)
                      shared java.logging/7 (already imported)
                  optional com.redhat.ceylon.module-resolver-aether/1.3.2
                  optional com.redhat.ceylon.module-resolver-javascript/1.3.2
                  optional com.redhat.ceylon.module-resolver-webdav/1.3.2
                  shared java.base/7 (already imported)
                  shared java.logging/7 (already imported)
                  javax.jaxws/7
                  javax.script/7
                  shared javax.xml/7
              shared java.base/7 (already imported)
              java.desktop/7 (already imported)
              shared java.logging/7 (already imported)
              shared optional org.tautua.markdownpapers.core/1.2.7
          shared com.redhat.ceylon.common/1.3.2 (already imported)
          shared com.redhat.ceylon.model/1.3.2 (already imported)
          shared com.redhat.ceylon.module-resolver/1.3.2 (already imported)
          com.redhat.ceylon.tool.provider/1.3.2
              ceylon.language/1.3.2 (already imported)
              shared com.redhat.ceylon.cli/1.3.2 (already imported)
              shared com.redhat.ceylon.common/1.3.2 (already imported)
              shared com.redhat.ceylon.compiler.java/1.3.2
                  ceylon.language/1.3.2 (already imported)
                  com.github.rjeschke.txtmark/0.13
                      shared java.base/7 (already imported)
                  shared com.redhat.ceylon.cli/1.3.2 (already imported)
                  shared com.redhat.ceylon.common/1.3.2 (already imported)
                  shared com.redhat.ceylon.langtools.classfile/1.3.2 (already imported)
                  shared com.redhat.ceylon.model/1.3.2 (already imported)
                  shared com.redhat.ceylon.module-resolver/1.3.2 (already imported)
                  shared com.redhat.ceylon.typechecker/1.3.2
                      shared com.redhat.ceylon.common/1.3.2 (already imported)
                      shared com.redhat.ceylon.model/1.3.2 (already imported)
                      shared com.redhat.ceylon.module-resolver/1.3.2 (already imported)
                      shared java.base/7 (already imported)
                      shared org.antlr.runtime/3.4
                          shared java.base/7 (already imported)
                          shared org.antlr.stringtemplate/3.2.1
                              shared java.base/7 (already imported)
                              shared java.desktop/7 (already imported)
                              shared org.antlr.antlr/2.7.7
                                  shared java.base/7 (already imported)
                                  shared java.desktop/7 (already imported)
                  shared java.base/7 (already imported)
                  shared java.compiler/7
                  java.desktop/7 (already imported)
                  java.logging/7 (already imported)
                  java.prefs/7
                  shared javax.xml/7 (already imported)
                  oracle.jdk.base/7
                  shared org.antlr.runtime/3.4 (already imported)
              com.redhat.ceylon.compiler.js/1.3.2
                  ceylon.language/1.3.2 (already imported)
                  shared com.redhat.ceylon.cli/1.3.2 (already imported)
                  shared com.redhat.ceylon.common/1.3.2 (already imported)
                  shared com.redhat.ceylon.model/1.3.2 (already imported)
                  shared com.redhat.ceylon.module-resolver/1.3.2 (already imported)
                  com.redhat.ceylon.module-resolver-javascript/1.3.2
                      net.minidev.json-smart/1.1.1
                          shared java.base/7 (already imported)
                  shared com.redhat.ceylon.typechecker/1.3.2 (already imported)
                  shared java.base/7 (already imported)
                  shared java.logging/7 (already imported)
                  net.minidev.json-smart/1.1.1 (already imported)
                  shared org.antlr.runtime/3.4 (already imported)
              com.redhat.ceylon.model/1.3.2 (already imported)
              com.redhat.ceylon.module-loader/1.3.2
                  ceylon.language/1.3.2 (already imported)
                  com.redhat.ceylon.common/1.3.2 (already imported)
                  com.redhat.ceylon.model/1.3.2 (already imported)
                  shared com.redhat.ceylon.module-resolver/1.3.2 (already imported)
                  shared java.base/7 (already imported)
                  optional org.jboss.modules/1.4.4.Final
              shared com.redhat.ceylon.module-resolver/1.3.2 (already imported)
              com.redhat.ceylon.typechecker/1.3.2 (already imported)
              shared java.base/7 (already imported)
              org.jboss.modules/1.4.4.Final
                  shared java.base/7 (already imported)
                  shared java.instrument/7
                  shared java.logging/7 (already imported)
                  java.management/7
                  java.prefs/7 (already imported)
                  shared javax.xml/7 (already imported)
                  oracle.jdk.base/7 (already imported)
          shared java.base/7 (already imported)
          java.compiler/7 (already imported)
          shared java.instrument/7 (already imported)
          javax.xml/7 (already imported)
          org.jboss.logmanager/2.0.3.Final
              shared java.base/7 (already imported)
              shared java.logging/7 (already imported)
              java.management/7 (already imported)
              shared java.tls/7
              optional org.jboss.modules/1.4.4.Final
          shared org.jboss.modules/1.4.4.Final (already imported)
      java.base/7 (already imported)
      org.jboss.modules/1.4.4.Final (already imported)
  shared fun.uschool.feature.impl/1.0.0
      ceylon.buffer/1.3.2 (already imported)
      ceylon.interop.java/1.3.2 (already imported)
      ceylon.language/1.3.2 (already imported)
      shared maven:com.moandjiezana.toml:toml4j/0.7.1
          maven:com.google.code.gson:gson/2.3.1
      shared fun.uschool.feature.spi/1.0.0
          ceylon.language/1.3.2 (already imported)
      shared java.base/8 (already imported other version)
      shared maven:org.jsimpledb:jsimpledb-main/3.5.0
          maven:com.google.code.findbugs:jsr305/3.0.1 PROVIDED
          maven:javax.el:javax.el-api/2.2.5
          maven:javax.validation:validation-api/1.1.0.Final
          maven:log4j:log4j/1.2.17 RUNTIME
              optional maven:javax.mail:mail/1.4.3
              optional maven:org.apache.geronimo.specs:geronimo-jms_1.1_spec/1.0
              maven:org.apache.openejb:javaee-api/5.0-2 PROVIDED
          maven:org.dellroad:dellroad-stuff-main/2.1.0
              optional maven:au.com.bytecode:opencsv/2.4
              maven:com.google.guava:guava/21.0
                  optional maven:com.google.code.findbugs:jsr305/1.3.9
                  optional maven:com.google.errorprone:error_prone_annotations/2.0.15
                  optional maven:com.google.j2objc:j2objc-annotations/1.1
                  optional maven:org.codehaus.mojo:animal-sniffer-annotations/1.14
              maven:javax.validation:validation-api/1.1.0.Final (already imported)
              optional maven:jline:jline/2.14.2
              optional maven:log4j:log4j/1.2.17
              optional maven:org.apache.ant:ant/1.9.7
              optional maven:org.hibernate.javax.persistence:hibernate-jpa-2.1-api/1.0.0.Final
              optional maven:org.hibernate:hibernate-core/5.0.7.Final
              maven:org.slf4j:slf4j-api/1.7.25
              maven:org.slf4j:slf4j-log4j12/1.7.25 RUNTIME
                  maven:log4j:log4j/1.2.17 (already imported)
                  maven:org.slf4j:slf4j-api/1.7.25 (already imported)
              optional maven:org.springframework:spring-context/4.3.7.RELEASE
          maven:org.hibernate:hibernate-validator/5.2.4.Final
              maven:com.fasterxml:classmate/1.1.0
              optional maven:com.thoughtworks.paranamer:paranamer/2.5.5
              maven:javax.el:javax.el-api/2.2.4 PROVIDED (already imported other version)
              maven:javax.validation:validation-api/1.1.0.Final (already imported)
              optional maven:joda-time:joda-time/2.7
              maven:org.glassfish.web:javax.el/2.2.4 PROVIDED
                  maven:javax.el:javax.el-api/2.2.4 (already imported other version)
              optional maven:org.hibernate.javax.persistence:hibernate-jpa-2.1-api/1.0.0.Final
              maven:org.jboss.logging:jboss-logging/3.2.1.Final
                  maven:log4j:log4j/1.2.16 PROVIDED (already imported other version)
                  maven:org.apache.logging.log4j:log4j-api/2.0 PROVIDED
                      maven:org.osgi:org.osgi.core/4.3.1 PROVIDED
                  maven:org.jboss.logmanager:jboss-logmanager/1.5.2.Final PROVIDED
                      optional maven:org.jboss.modules:jboss-modules/1.1.0.GA PROVIDED
                  maven:org.slf4j:slf4j-api/1.7.2 PROVIDED (already imported other version)
              maven:org.jboss.logging:jboss-logging-processor/1.2.0.Final PROVIDED
                  maven:org.jboss.jdeparser:jdeparser/1.0.0.Final
                  maven:org.jboss.logging:jboss-logging/3.1.2.GA PROVIDED (already imported other version)
                  maven:org.jboss.logging:jboss-logging-annotations/1.2.0.Final
                      maven:org.jboss.logging:jboss-logging/3.1.2.GA PROVIDED (already imported other version)
              optional maven:org.jsoup:jsoup/1.8.3
          shared maven:org.jsimpledb:jsimpledb-coreapi/3.5.0
              maven:com.google.code.findbugs:jsr305/3.0.1 PROVIDED (already imported)
              maven:commons-codec:commons-codec/1.10
              maven:log4j:log4j/1.2.17 RUNTIME (already imported other version)
              maven:org.dellroad:dellroad-stuff-main/2.1.0 (already imported)
              maven:org.jsimpledb:jsimpledb-kv/3.5.0
                  maven:com.google.code.findbugs:jsr305/3.0.1 PROVIDED (already imported)
                  maven:com.google.guava:guava/21.0 (already imported)
                  maven:log4j:log4j/1.2.17 RUNTIME (already imported other version)
                  maven:org.dellroad:dellroad-stuff-main/2.1.0 (already imported)
                  maven:org.jsimpledb:jsimpledb-util/3.5.0
                      maven:com.google.code.findbugs:jsr305/3.0.1 PROVIDED (already imported)
                      shared maven:com.google.guava:guava/21.0 (already imported)
                      maven:log4j:log4j/1.2.17 RUNTIME (already imported other version)
                      maven:org.slf4j:slf4j-api/1.7.25 (already imported other version)
                      maven:org.slf4j:slf4j-log4j12/1.7.25 RUNTIME (already imported)
                  maven:org.slf4j:slf4j-api/1.7.25 (already imported other version)
                  maven:org.slf4j:slf4j-log4j12/1.7.25 RUNTIME (already imported)
              shared maven:org.jsimpledb:jsimpledb-util/3.5.0 (already imported)
              maven:org.slf4j:slf4j-api/1.7.25 (already imported other version)
              maven:org.slf4j:slf4j-log4j12/1.7.25 RUNTIME (already imported)
          maven:org.jsimpledb:jsimpledb-kv/3.5.0 (already imported)
          maven:org.jsimpledb:jsimpledb-kv-simple/3.5.0
              maven:com.google.code.findbugs:jsr305/3.0.1 PROVIDED (already imported)
              maven:com.google.guava:guava/21.0 (already imported)
              maven:log4j:log4j/1.2.17 RUNTIME (already imported other version)
              maven:org.dellroad:dellroad-stuff-main/2.1.0 (already imported)
              maven:org.jsimpledb:jsimpledb-kv/3.5.0 (already imported)
              maven:org.jsimpledb:jsimpledb-util/3.5.0 (already imported)
              maven:org.slf4j:slf4j-api/1.7.25 (already imported other version)
              maven:org.slf4j:slf4j-log4j12/1.7.25 RUNTIME (already imported)
          maven:org.slf4j:slf4j-api/1.7.25 (already imported other version)
          maven:org.slf4j:slf4j-log4j12/1.7.25 RUNTIME (already imported)
  shared fun.uschool.feature.spi/1.0.0 (already imported)
  shared fun.uschool.user.api/1.0.0
      ceylon.language/1.3.2 (already imported)
      shared fun.uschool.feature.spi/1.0.0 (already imported)
      fun.uschool.user.impl/1.0.0
          ceylon.buffer/1.3.2 (already imported)
          ceylon.interop.java/1.3.2 (already imported)
          ceylon.language/1.3.2 (already imported)
          ceylon.test/1.3.2 (already imported)
          shared fun.uschool.feature.impl/1.0.0 (already imported)
          shared fun.uschool.feature.spi/1.0.0 (already imported)
          shared fun.uschool.user.api/1.0.0 (already imported)
          shared java.base/8 (already imported other version)
  shared java.base/8 (already imported other version)

Dependencies (up to depth ∞):
  ceylon.buffer/1.3.2
  ceylon.collection/1.3.2
  ceylon.file/1.3.2
  ceylon.interop.java/1.3.2
  ceylon.language/1.3.2
  ceylon.runtime/1.3.2
  ceylon.test/1.3.2
  com.fasterxml:classmate/1.1.0
  com.github.rjeschke.txtmark/0.13
  com.google.code.findbugs:jsr305/3.0.1
  com.google.code.gson:gson/2.3.1
  com.google.guava:guava/21.0
  com.moandjiezana.toml:toml4j/0.7.1
  com.redhat.ceylon.cli/1.3.2
  com.redhat.ceylon.common/1.3.2
  com.redhat.ceylon.compiler.java/1.3.2
  com.redhat.ceylon.compiler.js/1.3.2
  com.redhat.ceylon.langtools.classfile/1.3.2
  com.redhat.ceylon.model/1.3.2
  com.redhat.ceylon.module-loader/1.3.2
  com.redhat.ceylon.module-resolver/1.3.2
  com.redhat.ceylon.module-resolver-javascript/1.3.2
  com.redhat.ceylon.tool.provider/1.3.2
  com.redhat.ceylon.typechecker/1.3.2
  commons-codec:commons-codec/1.10
  fun.uschool.feature.impl/1.0.0
  fun.uschool.feature.spi/1.0.0
  fun.uschool.user.api/1.0.0
  fun.uschool.user.impl/1.0.0
  java.base: 7, 8
  java.compiler/7
  java.desktop/7
  java.instrument/7
  java.logging/7
  java.management/7
  java.prefs/7
  java.tls/7
  javax.el:javax.el-api: 2.2.4, 2.2.5
  javax.jaxws/7
  javax.script/7
  javax.validation:validation-api/1.1.0.Final
  javax.xml/7
  log4j:log4j: 1.2.16, 1.2.17
  net.minidev.json-smart/1.1.1
  oracle.jdk.base/7
  org.antlr.antlr/2.7.7
  org.antlr.runtime/3.4
  org.antlr.stringtemplate/3.2.1
  org.apache.logging.log4j:log4j-api/2.0
  org.apache.openejb:javaee-api/5.0-2
  org.dellroad:dellroad-stuff-main/2.1.0
  org.glassfish.web:javax.el/2.2.4
  org.hibernate:hibernate-validator/5.2.4.Final
  org.jboss.jdeparser:jdeparser/1.0.0.Final
  org.jboss.logging:jboss-logging: 3.1.2.GA, 3.2.1.Final
  org.jboss.logging:jboss-logging-annotations/1.2.0.Final
  org.jboss.logging:jboss-logging-processor/1.2.0.Final
  org.jboss.logmanager/2.0.3.Final
  org.jboss.logmanager:jboss-logmanager/1.5.2.Final
  org.jboss.modules/1.4.4.Final
  org.jsimpledb:jsimpledb-coreapi/3.5.0
  org.jsimpledb:jsimpledb-kv/3.5.0
  org.jsimpledb:jsimpledb-kv-simple/3.5.0
  org.jsimpledb:jsimpledb-main/3.5.0
  org.jsimpledb:jsimpledb-util/3.5.0
  org.osgi:org.osgi.core/4.3.1
  org.slf4j:slf4j-api: 1.7.2, 1.7.25
  org.slf4j:slf4j-log4j12/1.7.25

Dependencies version conflicts (up to depth ∞):
  java.base: 7, 8
  javax.el:javax.el-api: 2.2.4, 2.2.5
  log4j:log4j: 1.2.16, 1.2.17
  org.jboss.logging:jboss-logging: 3.1.2.GA, 3.2.1.Final
  org.slf4j:slf4j-api: 1.7.2, 1.7.25

Body:
Okay, I got it. The problem was that RoleConverter converts to ceylon.language.String, while the api was expecting a converter to java.lang.String. Fixed it now:

shared class RoleConverter() extends Converter<Role, JString>() {
    shared actual Role doBackward(JString? name) {
        "Cannot convert null to role."
        assert (exists name);
        return Role.ofName(name.string);
    }

    shared actual JString doForward(Role? role) {
        return JString(role?.name else "null");
    }
}


来源: stackexchange

问:
Get Value from an html form and put into an array
I have a form and a button with a function that create dynamically a textfield and set the name with an index like below:
corso_1
corso_2
corso_3

So.. a php function get all the value of this form and add all in an array, so how can i get all the value into the dynamic textfields?

答:
just put the all data with jquery in that dynamic textfield.by looping throught Real_data array and set index as Real_data['corso_'+i] and here i is a for loop variable.

& $('#corso') is the form id.

hope it helps.

```<code>  var data = $('#corso').serializeArray();
  var Real_data = {}; //this array is used to store sorted data
  $(data).each(function(i,field){
     Real_data[field.name] = field.value;
  });
</code>```

ContentLicense: CC BY-SA 3.0

Body:
just put the all data with jquery in that dynamic textfield.by looping throught Real_data array and set index as Real_data['corso_'+i] and here i is a for loop variable.

& $('#corso') is the form id.

hope it helps.

  var data = $('#corso').serializeArray();
  var Real_data = {}; //this array is used to store sorted data
  $(data).each(function(i,field){
     Real_data[field.name] = field.value;
  });


问:
python3: two clients sending data to server using sockets
I'm working with 3 raspberry pi, one as a server and the two others are clients. What I want to do is to make the clients communicate with the server simultaneously, I don't want to wait for client1 communication to be done in order to launch client2 request to the server (which I succeeded to do). However, I want each client to send different data to server at the same time. I tried to use Sockets and threading, like below.

server code:

```<code>import socket
import RPi.GPIO as GPIO
from threading import Thread

# Multithreaded Python server : TCP Server Socket Thread Pool
class ClientThread(Thread):

    def __init__(self,ip,port):
        Thread.__init__(self)
        self.ip = ip
        self.port = port
        print ("[+] New server socket thread started for " + ip + ":" + str(port))

    def run(self):
        while True :
            data = conn.recv(2048)
            data = data.decode('utf-8')
            print ("Server received data:", data)
            MESSAGE = input("Multithreaded Python server : Enter Response from Server/Enter exit:")
            if MESSAGE == 'exit':
                break
            conn.send(str.encode(MESSAGE))  # echo

# Multithreaded Python server : TCP Server Socket Program Stub
TCP_IP = ''
TCP_PORT = 9050
BUFFER_SIZE = 2000  # Usually 1024, but we need quick response

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

s.bind((TCP_IP, TCP_PORT))
s.listen(2)
threads = []
list_data=[]

while True:

    print ("Multithreaded Python server : Waiting for connections from TCP clients...")
    (conn, (ip,port)) = s.accept()
    data = conn.recv(2048)
    newthread = ClientThread(ip,port)
    newthread.start()
    threads.append(newthread)
    list_data.append(data)

for t in threads:
    t.join()
</code>```

client1 code:

```<code>import socket
import RPi.GPIO as GPIO
import time

host = '192.168.0.198'
port = 9050
BUFFER_SIZE = 2000
MESSAGE = input("tcpClient1: Enter message/ Enter exit:")

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))

while MESSAGE != 'exit':
    s.send(str.encode(MESSAGE))
    data = s.recv(BUFFER_SIZE)
    data = data.decode('utf-8')
    print (" Client2 received data:", data)
    MESSAGE = input("tcpClient2: Enter message to continue/ Enter exit:")
</code>```

client2 code:

```<code>import socket
import RPi.GPIO as GPIO
import time

import socket

host = '192.168.0.198'
port = 9050
BUFFER_SIZE = 2000
MESSAGE = input("tcpClient2: Enter message/ Enter exit:")

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))

while MESSAGE != 'exit':
    s.send(str.encode(MESSAGE))
    data = s.recv(BUFFER_SIZE)
    data = data.decode('utf-8')
    print (" Client received data:", data)
    MESSAGE = input("tcpClient2: Enter message to continue/ Enter exit:")
</code>```

when i run, i obtain:
 in the server terminal:

```<code>Multithreaded Python server : Waiting for connections from TCP clients...
[+] New server socket thread started for 192.168.0.197:47012
Multithreaded Python server : Waiting for connections from TCP clients...
[+] New server socket thread started for 192.168.0.196:47886
Multithreaded Python server : Waiting for connections from TCP clients...
</code>```

in client1 terminal:

```<code>tcpClient1: Enter message/ Enter exit:begin
</code>```

in client2 terminal:

```<code>tcpClient2: Enter message/ Enter exit:begin
</code>```

It seems like server didn't receive or send any data.

答:
As @Hikke mentioned in his comment, your server receives at two different places. The conn.recv call in this code snippet eats up the data that the server receiving thread is expecting. Remove data = conn.recv(2048) in your server's main loop:

```<code>while True:

    print ("Multithreaded Python server : Waiting for connections from TCP clients...")
    (conn, (ip,port)) = s.accept()
    data = conn.recv(2048) # <== dont eat the data of your thread here!
    newthread = ClientThread(ip,port)
    newthread.start()
    threads.append(newthread)
    list_data.append(data)
</code>```

Body:
I'm working with 3 raspberry pi, one as a server and the two others are clients. What I want to do is to make the clients communicate with the server simultaneously, I don't want to wait for client1 communication to be done in order to launch client2 request to the server (which I succeeded to do). However, I want each client to send different data to server at the same time. I tried to use Sockets and threading, like below.

server code:

import socket
import RPi.GPIO as GPIO
from threading import Thread

# Multithreaded Python server : TCP Server Socket Thread Pool
class ClientThread(Thread):

    def __init__(self,ip,port):
        Thread.__init__(self)
        self.ip = ip
        self.port = port
        print ("[+] New server socket thread started for " + ip + ":" + str(port))

    def run(self):
        while True :
            data = conn.recv(2048)
            data = data.decode('utf-8')
            print ("Server received data:", data)
            MESSAGE = input("Multithreaded Python server : Enter Response from Server/Enter exit:")
            if MESSAGE == 'exit':
                break
            conn.send(str.encode(MESSAGE))  # echo

# Multithreaded Python server : TCP Server Socket Program Stub
TCP_IP = ''
TCP_PORT = 9050
BUFFER_SIZE = 2000  # Usually 1024, but we need quick response

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

s.bind((TCP_IP, TCP_PORT))
s.listen(2)
threads = []
list_data=[]

while True:

    print ("Multithreaded Python server : Waiting for connections from TCP clients...")
    (conn, (ip,port)) = s.accept()
    data = conn.recv(2048)
    newthread = ClientThread(ip,port)
    newthread.start()
    threads.append(newthread)
    list_data.append(data)

for t in threads:
    t.join()

client1 code:

import socket
import RPi.GPIO as GPIO
import time

host = '192.168.0.198'
port = 9050
BUFFER_SIZE = 2000
MESSAGE = input("tcpClient1: Enter message/ Enter exit:")

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))

while MESSAGE != 'exit':
    s.send(str.encode(MESSAGE))
    data = s.recv(BUFFER_SIZE)
    data = data.decode('utf-8')
    print (" Client2 received data:", data)
    MESSAGE = input("tcpClient2: Enter message to continue/ Enter exit:")

client2 code:

import socket
import RPi.GPIO as GPIO
import time

import socket

host = '192.168.0.198'
port = 9050
BUFFER_SIZE = 2000
MESSAGE = input("tcpClient2: Enter message/ Enter exit:")

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))

while MESSAGE != 'exit':
    s.send(str.encode(MESSAGE))
    data = s.recv(BUFFER_SIZE)
    data = data.decode('utf-8')
    print (" Client received data:", data)
    MESSAGE = input("tcpClient2: Enter message to continue/ Enter exit:")

when i run, i obtain:
 in the server terminal:

Multithreaded Python server : Waiting for connections from TCP clients...
[+] New server socket thread started for 192.168.0.197:47012
Multithreaded Python server : Waiting for connections from TCP clients...
[+] New server socket thread started for 192.168.0.196:47886
Multithreaded Python server : Waiting for connections from TCP clients...

in client1 terminal:

tcpClient1: Enter message/ Enter exit:begin

in client2 terminal:

tcpClient2: Enter message/ Enter exit:begin

It seems like server didn't receive or send any data.

Body:
As @Hikke mentioned in his comment, your server receives at two different places. The conn.recv call in this code snippet eats up the data that the server receiving thread is expecting. Remove data = conn.recv(2048) in your server's main loop:

while True:

    print ("Multithreaded Python server : Waiting for connections from TCP clients...")
    (conn, (ip,port)) = s.accept()
    data = conn.recv(2048) # <== dont eat the data of your thread here!
    newthread = ClientThread(ip,port)
    newthread.start()
    threads.append(newthread)
    list_data.append(data)


问:
Firebase: How to load top posts without similarly scored posts getting skipped?
I implemented infinite scrolling in my web app using firebase.

In my "Top" section, I show the highest upvoted posts of users.

The issue, is that in my current implementation, a few posts are skipped.

That is, if many posts have the same score, some will just not appear.

I understand why this is happening, I load my posts by lot of 12, and then select the next lot by doing this:

```<code>start = childDataSnapshot.child("inversedScore").val() + 1;
</code>```

The issue with this approach is that if there are more than 12 elements with the same vote score, or if there are 2 elements with the same vote score, one being number 12 and the other number 13, then number 13 gets ignored and we directly go the next score level.

For example, here is my data on the server:

```<code>post1: score: 15
post2: score: 14
post3: score: 13
post4: score: 12
post5: score: 11
post6: score: 10
post7: score: 10
post8: score: 9
post9: score: 9
post10: score: 9
post11: score: 8
post12: score: 7

//posts 13 and 14 will be ignored
post13: score: 7
post14: score: 7

post15: score: 6
post16: score: 6
</code>```

Here is what I will see on the client:

```<code>post1: score: 15
post2: score: 14
post3: score: 13
post4: score: 12
post5: score: 11
post6: score: 10
post7: score: 10
post8: score: 9
post9: score: 9
post10: score: 9
post11: score: 8
post12: score: 7
post15: score: 6
post16: score: 6
</code>```

What other approach is there to loading the top  posts with firebase so that top posts with the same score are never "skipped" ?

client:

```<code>var started = false;

app.controller('ctrl', function ($scope, $firebaseArray, $timeout) {

    if(started == false) {
        started = true;

        $scope.bricks = [];
        var _n = 12;

        if ( $(window).width() < 992) {
          _n = 2;
        }

        var firstElementsLoaded = false;
        var _start = -1000000000;
        var position = 0;

        $scope.getDataset = function() {
            var sendObject = {
                start: _start,
                section: section,
                n: _n,
            }
            $.ajax({
                type: "POST",
                url: "images/top",
                data: sendObject,
            }).done(function(result) {
                for (var i = 0; i < result.array.length; i++) {
                    console.log("result: "+result.array[i]);
                    $scope.bricks.push(result.array[i]);
                    $scope.$apply();
                }

                _start = result.start;
                firstElementsLoaded = true;
            });
        };

        $scope.getDataset();

        var screenHeight;
        var existingScreenHeight

        if ( $(window).width() < 992) {
            screenHeight = (_n + 1) * 350;
            existingScreenHeight = -350;
        }
        else {
            screenHeight = 1 * Math.ceil($(window).height());
            existingScreenHeight = -screenHeight;
        }

        window.addEventListener('scroll', function() {

            if (firstElementsLoaded == true) {
               if (window.scrollY >= ((screenHeight) + existingScreenHeight)) {
                  existingScreenHeight += (screenHeight);
                  $scope.$apply($scope.getDataset());
                  firstElementsLoaded = false;
               }
            }
        });
    }
});

angular.bootstrap(document.body, ['app']);
</code>```

server:

```<code>router.post('/images/top', function(req, res, next) {
    var start = parseInt(req.body.start);
    var section = req.body.section;
    var n = parseInt(req.body.n);
    var returnArray = [];
    var screenshotRef = admin.database().ref("posts/"+section);
    screenshotRef.orderByChild("inversedScore").startAt(start).limitToFirst(n).once("value", function(dataSnapshot) {

        dataSnapshot.forEach(function(childDataSnapshot) {

            start = childDataSnapshot.child("inversedScore").val() + 1;

            var post = childDataSnapshot.val();

            var file = bucket.file(post.image);

            var config = {
              action: 'read',
              expires: Date.now() + global.expiryTime,
            };

            file.getSignedUrl(config, function(err, url) {
                if (err) {
                    console.error(err);
                    return;
                }
                post.image = url;
                returnArray.push(post);
                if (returnArray.length == n) {
                    var returnObject = {
                        start: start,
                        array: returnArray
                    }
                    res.send(returnObject);
                }
            });
        });
    });
});
</code>```

答:
You can easily skip the extra item (typically referred to as the anchor item) in the client. You cannot skip it in the query. If you pass in the anchor item's key as a second parameter, you can ensure there is only a single overlapping item.

See these previous questions:

Firebase Query order by and start at name

How to paging query from Firebase using Android FirebaseUI

Firebase range query

Let me know if you have questions about this, because it's definitely not the most intuitive part of the API.

Body:
I implemented infinite scrolling in my web app using firebase.

In my "Top" section, I show the highest upvoted posts of users.

The issue, is that in my current implementation, a few posts are skipped.

That is, if many posts have the same score, some will just not appear.

I understand why this is happening, I load my posts by lot of 12, and then select the next lot by doing this:

start = childDataSnapshot.child("inversedScore").val() + 1;

The issue with this approach is that if there are more than 12 elements with the same vote score, or if there are 2 elements with the same vote score, one being number 12 and the other number 13, then number 13 gets ignored and we directly go the next score level.

For example, here is my data on the server:

post1: score: 15
post2: score: 14
post3: score: 13
post4: score: 12
post5: score: 11
post6: score: 10
post7: score: 10
post8: score: 9
post9: score: 9
post10: score: 9
post11: score: 8
post12: score: 7

//posts 13 and 14 will be ignored
post13: score: 7
post14: score: 7

post15: score: 6
post16: score: 6

Here is what I will see on the client:

post1: score: 15
post2: score: 14
post3: score: 13
post4: score: 12
post5: score: 11
post6: score: 10
post7: score: 10
post8: score: 9
post9: score: 9
post10: score: 9
post11: score: 8
post12: score: 7
post15: score: 6
post16: score: 6

What other approach is there to loading the top  posts with firebase so that top posts with the same score are never "skipped" ?

client:

var started = false;

app.controller('ctrl', function ($scope, $firebaseArray, $timeout) {

    if(started == false) {
        started = true;

        $scope.bricks = [];
        var _n = 12;

        if ( $(window).width() < 992) {
          _n = 2;
        }

        var firstElementsLoaded = false;
        var _start = -1000000000;
        var position = 0;

        $scope.getDataset = function() {
            var sendObject = {
                start: _start,
                section: section,
                n: _n,
            }
            $.ajax({
                type: "POST",
                url: "images/top",
                data: sendObject,
            }).done(function(result) {
                for (var i = 0; i < result.array.length; i++) {
                    console.log("result: "+result.array[i]);
                    $scope.bricks.push(result.array[i]);
                    $scope.$apply();
                }

                _start = result.start;
                firstElementsLoaded = true;
            });
        };

        $scope.getDataset();

        var screenHeight;
        var existingScreenHeight

        if ( $(window).width() < 992) {
            screenHeight = (_n + 1) * 350;
            existingScreenHeight = -350;
        }
        else {
            screenHeight = 1 * Math.ceil($(window).height());
            existingScreenHeight = -screenHeight;
        }

        window.addEventListener('scroll', function() {

            if (firstElementsLoaded == true) {
               if (window.scrollY >= ((screenHeight) + existingScreenHeight)) {
                  existingScreenHeight += (screenHeight);
                  $scope.$apply($scope.getDataset());
                  firstElementsLoaded = false;
               }
            }
        });
    }
});

angular.bootstrap(document.body, ['app']);

server:

router.post('/images/top', function(req, res, next) {
    var start = parseInt(req.body.start);
    var section = req.body.section;
    var n = parseInt(req.body.n);
    var returnArray = [];
    var screenshotRef = admin.database().ref("posts/"+section);
    screenshotRef.orderByChild("inversedScore").startAt(start).limitToFirst(n).once("value", function(dataSnapshot) {

        dataSnapshot.forEach(function(childDataSnapshot) {

            start = childDataSnapshot.child("inversedScore").val() + 1;

            var post = childDataSnapshot.val();

            var file = bucket.file(post.image);

            var config = {
              action: 'read',
              expires: Date.now() + global.expiryTime,
            };

            file.getSignedUrl(config, function(err, url) {
                if (err) {
                    console.error(err);
                    return;
                }
                post.image = url;
                returnArray.push(post);
                if (returnArray.length == n) {
                    var returnObject = {
                        start: start,
                        array: returnArray
                    }
                    res.send(returnObject);
                }
            });
        });
    });
});


问:
How to open excel file using Javascript in chrome?
I have tried this code but it does not work in the chrome</p>

```<code>var myApp = new ActiveXObject("Excel.Application");
myApp.workbooks.open("test.xls");
</code>```

答:
ActiveXObject is available only on IE browser. So every other useragent will throw an error

On modern browser you could use instead File API or File writer API (currently implemented only on Chrome)

Body:
I have tried this code but it does not work in the chrome

var myApp = new ActiveXObject("Excel.Application");
myApp.workbooks.open("test.xls");


问:
React Router defining my own Link
So the implementation of the <Link /> onClick which handles the router navigation is simple:

```<code>const { history } = this.context.router;

history.push(to);
</code>```

That is pulled from the github repo

So in my application it should work, because the context gets passed down from the <Router> component right?

```<code>class App extends React.Component {
  constructor() {
    super(...arguments);
  }

  render() {
    const home = () => (<div>Home</div>);
    const about = () => (<div>About</div>);
    const { history } = this.context.router;

    console.log("History", history);

    return (
      <div>
        <ul>
          <li><Link to="/">Home</Link></li>
          <li><Link to="/about">About</Link></li>
        </ul>

        <Route exact path="/" component={home} />
        <Route path="/about" component={about} />
      </div>
    )
  }
}

ReactDOM.render(
  <Router>
    <App />
  </Router>,
  document.getElementById('main')
);
</code>```

But as you can see in the console output, the history object is undefined....

答:
Just to clarify Azium comment:

```<code>class App extends React.Component {
  constructor() {
    super(...arguments);
  }

  render() {
    const home = () => (<div>Home</div>);
    const about = () => (<div>About</div>);
    const { history } = this.props;

    console.log("History", history);

    return (
      <div>
        <ul>
          <li><Link to="/">Home</Link></li>
          <li><Link to="/about">About</Link></li>
        </ul>

        <Route exact path="/" component={home} />
        <Route path="/about" component={about} />
      </div>
    )
  }
}

const AppWithRouter = withRouter(App);

ReactDOM.render(
  <Router>
    <AppWithRouter />
  </Router>,
  document.getElementById('main')
);
</code>```

withRouter gives you match, location, history on the props.

Title: React Router defining my own Link

Body:
So the implementation of the <Link /> onClick which handles the router navigation is simple:

const { history } = this.context.router;

history.push(to);

That is pulled from the github repo

So in my application it should work, because the context gets passed down from the <Router> component right?

class App extends React.Component {
  constructor() {
    super(...arguments);
  }

  render() {
    const home = () => (
Home
);
    const about = () => (
About
);
    const { history } = this.context.router;

    console.log("History", history);

    return (

<Link to="/">Home</Link>

<Link to="/about">About</Link>

        <Route exact path="/" component={home} />
        <Route path="/about" component={about} />

    )
  }
}

ReactDOM.render(
  <Router>
    <App />
  </Router>,
  document.getElementById('main')
);

But as you can see in the console output, the history object is undefined....

Body:
Just to clarify Azium comment:

class App extends React.Component {
  constructor() {
    super(...arguments);
  }

  render() {
    const home = () => (<div>Home</div>);
    const about = () => (<div>About</div>);
    const { history } = this.props;

    console.log("History", history);

    return (
      <div>
        <ul>
          <li><Link to="/">Home</Link></li>
          <li><Link to="/about">About</Link></li>
        </ul>

        <Route exact path="/" component={home} />
        <Route path="/about" component={about} />
      </div>
    )
  }
}

const AppWithRouter = withRouter(App);

ReactDOM.render(
  <Router>
    <AppWithRouter />
  </Router>,
  document.getElementById('main')
);

withRouter gives you match, location, history on the props.


问:
Open Perspective programmatically
I am trying to provide a command/ handler to switch to a specific Perspective.

I came up with the following class:

```<code>public class OpenPerspectiveHandler {

    private static final Logger logger = Logger.getLogger(OpenPerspectiveHandler.class);
    @Inject
    private MApplication application;
    @Inject
    private EModelService modelService;
    @Inject
    private EPartService partService;
    private final String perspectiveId;

    public OpenPerspectiveHandler(String perspectiveId) {
        super();
        this.perspectiveId = perspectiveId;
    }

    public void changePerspective(String perspectiveId) {

        Optional<MPerspective> perspective = findPerspective();
        if(perspective.isPresent()) {
            partService.switchPerspective(perspective.get());
        } else {
            logger.debug("Perspective not found (" + perspectiveId + ")");
        }
    }

    @Execute
    public void execute() {

        changePerspective(perspectiveId);
    }

    private Optional<MPerspective> findPerspective() {

        MUIElement element = modelService.find(perspectiveId, application);
        if(element instanceof MPerspective) {
            return Optional.of((MPerspective)element);
        } else {
            logger.debug("Wrong type " + element);
        }
        return Optional.empty();
    }

    @Override
    public String toString() {

        return "OpenPerspectiveHandler [application=" + application + ", modelService=" + modelService + ", partService=" + partService + ", perspectiveId=" + perspectiveId + "]";
    }
}
</code>```

Interestingly, this works only once. A workaround is to cache MPerspective once it was found and not to use modelService.find(perspectiveId, application) again.

Why does it work only once? modelService.find(perspectiveId, application) returns null after the first execution.

EDIT:

Another approach (as suggested by greg-449) is the following:

```<code>public class OpenPerspectiveHandler {

    private static final Logger logger = Logger.getLogger(OpenPerspectiveHandler.class);
    private final String perspectiveId;

    public OpenPerspectiveHandler(String perspectiveId) {
        super();
        this.perspectiveId = perspectiveId;
    }

    @Execute
    public void changePerspective(MApplication application, EModelService modelService, EPartService partService) {

        Optional<MPerspective> perspective = findPerspective(application, modelService);
        if(perspective.isPresent()) {
            partService.switchPerspective(perspective.get());
        } else {
            logger.debug("Perspective not found (" + perspectiveId + ")");
        }
    }

    private Optional<MPerspective> findPerspective(MApplication application, EModelService modelService) {

        MUIElement element = modelService.find(perspectiveId, application);
        if(element instanceof MPerspective) {
            return Optional.of((MPerspective)element);
        } else {
            logger.debug("Wrong type " + element);
        }
        return Optional.empty();
    }
}
</code>```

But this approach also changes the perspective only once. modelService.find(perspectiveId, application); returns null after the first execution.

答:
The EPartService varies depending on the context that the handler runs in. In some cases you get the Application part service which only works if there is an active window.

You can get the part service for that window using something like:

MWindow window = (MWindow)modelService.find("top window id", application);

IEclipseContext windowContext = window.getContext();

EPartService windowPartService = windowContext.get(EPartService.class);
```

Title: Open Perspective programmatically

Body:
I am trying to provide a command/ handler to switch to a specific Perspective.

I came up with the following class:

public class OpenPerspectiveHandler {

    private static final Logger logger = Logger.getLogger(OpenPerspectiveHandler.class);
    @Inject
    private MApplication application;
    @Inject
    private EModelService modelService;
    @Inject
    private EPartService partService;
    private final String perspectiveId;

    public OpenPerspectiveHandler(String perspectiveId) {
        super();
        this.perspectiveId = perspectiveId;
    }

    public void changePerspective(String perspectiveId) {

        Optional<MPerspective> perspective = findPerspective();
        if(perspective.isPresent()) {
            partService.switchPerspective(perspective.get());
        } else {
            logger.debug("Perspective not found (" + perspectiveId + ")");
        }
    }

    @Execute
    public void execute() {

        changePerspective(perspectiveId);
    }

    private Optional<MPerspective> findPerspective() {

        MUIElement element = modelService.find(perspectiveId, application);
        if(element instanceof MPerspective) {
            return Optional.of((MPerspective)element);
        } else {
            logger.debug("Wrong type " + element);
        }
        return Optional.empty();
    }

    @Override
    public String toString() {

        return "OpenPerspectiveHandler [application=" + application + ", modelService=" + modelService + ", partService=" + partService + ", perspectiveId=" + perspectiveId + "]";
    }
}

Interestingly, this works only once. A workaround is to cache MPerspective once it was found and not to use modelService.find(perspectiveId, application) again.

Why does it work only once? modelService.find(perspectiveId, application) returns null after the first execution.

EDIT:

Another approach (as suggested by greg-449) is the following:

public class OpenPerspectiveHandler {

    private static final Logger logger = Logger.getLogger(OpenPerspectiveHandler.class);
    private final String perspectiveId;

    public OpenPerspectiveHandler(String perspectiveId) {
        super();
        this.perspectiveId = perspectiveId;
    }

    @Execute
    public void changePerspective(MApplication application, EModelService modelService, EPartService partService) {

        Optional<MPerspective> perspective = findPerspective(application, modelService);
        if(perspective.isPresent()) {
            partService.switchPerspective(perspective.get());
        } else {
            logger.debug("Perspective not found (" + perspectiveId + ")");
        }
    }

    private Optional<MPerspective> findPerspective(MApplication application, EModelService modelService) {

        MUIElement element = modelService.find(perspectiveId, application);
        if(element instanceof MPerspective) {
            return Optional.of((MPerspective)element);
        } else {
            logger.debug("Wrong type " + element);
        }
        return Optional.empty();
    }
}

But this approach also changes the perspective only once. modelService.find(perspectiveId, application); returns null after the first execution.


问:
How to let asynchronous readFile method follow order in node.js
I have a code like this

```<code>var fs = require('fs');
console.log("1");
fs.readFile("./index.js", function(err, data) {
    if (err) {
         console.log("err");
    }
    console.log("2");
});
console.log("3");
</code>```

and the result will be

```<code>1
3
2
</code>```

But I want 1 2 3 I have look through filesystem's document and it says With the asynchronous methods there is no guaranteed ordering.  so the document says if I want my code result 1 2 3 it should be

```<code>var fs = require('fs');
console.log("1");
fs.readFile("./index.js", function(err, data) {
    if (err) {
         console.log("err");
    }
    console.log("2");
    console.log("3");
});
</code>```

But it's for short code if I'm building a system which has a lot of other function needs to be after this code we can't nested all in because the function need to be work after it will be use by other functions so is there a way to let the fs.readFile work in order but not incuding all the code need to work after it in fs code?

code I have issue

```<code>function servedatastart() {

    if (urlcontentbasic(urlslug) != "err") {
        responsearray["data"] = urlcontentbasic(urlslug);
    } else {
        // callback function
        console.log("urlex");
        urlex("none", urlslug); // this function I use fs.readFile(urlslug, function...
    }
    console.log("other function");
    //other function
    cuswriteheader();
    includescript();
    writefooter()
    res.end();
}
</code>```

答:
The simple solution is to just put the rest of your code that you want to execute after the fs.readFile() operation into a function and then insert that function into the async callback:

```<code>var fs = require('fs');
console.log("1");
fs.readFile("./index.js", function(err, data) {
    if (err) {
         console.log("err");
    }
    console.log("2");
    moreCode();
});

function moreCode() {
    console.log("3");
}
</code>```

A bit more modern design is to use promises for all your asynchronous operations and then you can sequence things a bit easier.

```<code>const Promise = require('bluebird');
const fs = Promise.promisifyAll(require('fs'));

console.log("1");
fs.readFileAsync("./index.js").then((data) => {
    console.log("2");
    return moreCode();
}).catch((err) => {
    // handle error here
});

function moreCode() {
    console.log("3");
}
</code>```

Where the benefit of using promises really starts to take advantage is when you have multiple asynchronous operations that you want to sequence and each one returns a promise.  Then, you can do that like this:

```<code>const Promise = require('bluebird');
const fs = Promise.promisifyAll(require('fs'));

fs.readFileAsync("./index.js")
  .then(moreCode1)
  .then(moreCode2)
  .catch((err) => {
      // handle error here
  });
</code>```

Using the code you've show for the urlex() function, here's how you can make all that work using promises:

```<code>// include infrastructure to automatically promisify the fs module
const Promise = require('bluebird');
const fs = Promise.promisifyAll(require('fs'));

function servedatastart() {

    Promise.resolve().then(function() {
        if (urlcontentbasic(urlslug) != "err") {
            // I'm assuming that urlcontentbasic is also async and returns a promise
            // like urlexbasic does
            return urlcontentbasic(urlslug);
        } else {
            // callback function
            console.log("urlex");
            return urlex("none", urlslug);
        }
    }).then(function() {
        console.log("other function");
        //other function
        cuswriteheader();
        includescript();
        writefooter()
        res.end();
    });
}

// basic function for reading extension-less URL
// returns a promise whose resolved value is a returnarray data structure
function urlexbasic(filetype, slug) {
    var returnarray = {status:null,contenttype:null,data:null,message:undefined};
    if (slug == undefined) {
        slug = "";
    }

    if (filetype == "none") {
        var filename;
        console.log("path: "+pathdataarray["1"]);
        if (pathdataarray["1"] == "/pre") {
            console.log("substr");
            filename = urlslug.substr(4, urlslug.length-5);
            console.log("1: "+filename);
        }
        urldata(q.pathname, "");
        console.log("slug: "+ slug+" filename: "+ filename);
        if (slug != "" || filename != undefined) {
            console.log("what?")
            if (filename != undefined) {
                filename = "." + filename;
            } else {
                filename = "." + slug;
            }
            console.log("2: "+filename);
        } else {
            filename = "." + urlslug.substr(0, urlslug.length-1);
        }
        console.log("filename: "+ filename);
        return fs.readFileAsync(filename.substr(0, filename.length-1), 'utf8').then(function(data) {
            console.log("readfile");
            var mime = null;
            if (urldataarray.extension == "js") {
                mime = "javascript";
            } else {
                mime = urldataarray.extension;
            }
            console.log("hey running");
            returnarray["status"] = 200;
            returnarray["contenttype"] = 'text/'+mime;
            //res.writeHead(200, {'contenttype': 'text/'+mime});
            returnarray["data"] = data;
            console.log("instatus: "+returnarray["status"]);
            // make returnarray be the resolved value of the promise
            return returnarray;
        }).catch(function(err) {
            console.log("404 error");
            returnarray["status"] = 404;
        });
    } else {
        urldata(q.pathname, filetype);
        var filename;
        if (pathdataarray["1"] == "/pre") {
            console.log("substr");
            filename = urlslug.substr(4, urlslug.length-5);
            console.log("11: "+filename);
        }
        console.log("2slug: "+ slug+" filename: "+ filename);
        if (slug != "" || filename != undefined) {
            if (filename) {
                filename = "." + filename + "." + filetype;
            } else {
                filename = "." + slug +"."+ filetype;
            }
            console.log("22: "+filename);
        } else {
            filename = "." + urlslug.substr(0, urlslug.length-1) + "." + filetype;
        }
        return fs.readFileAsync(filename, 'utf8').then(function(data) {
            var mime = null;
            if (urldataarray.extension == "js") {
                mime = "javascript";
            } else {
                mime = urldataarray.extension;
                console.log("ok");
            };

            if (pathdataarray["1"] == "/pre") {
                returnarray["status"] = 200;
                returnarray["contenttype"] = 'text/plain';
                //res.writeHead(200, {'contenttype': 'text/plain'});
                //res.write("```");
                returnarray["data"] = data;
                //res.write("```");
            } else {
                returnarray["status"] = 200;
                returnarray["contenttype"] = 'text/'+mime;
                //res.writeHead(200, {'contenttype': 'text/'+mime});
                console.log("pure data");
                returnarray["data"] = data;
            }
            // make returnarray be the resolved value of the promise
            return returnArray;
        }).catch(function(err) {
            return urlex(dataerrcall[filetype]);
        });
    }
}

// returns a promise whose resolved value is a returnArray
function urlex(filetypeex, slugex) {
    //console.log(urlexbasic(filetypeex, slugex));
    return urlexbasic(filetypeex, slugex).then(function(returnArray) {
        console.log("return: "+returnarray.status);
        responsearray["status"] = returnarray["status"];

        responsearray["contenttype"] = returnarray["contenttype"]
        responsearray["message"] = returnarray["message"];
        responsearray["data"] = returnarray["data"];
        return responsearray;
    });
}
</code>```

This uses several nice promise features such as chaining (to sequence async operations).

Body:
I have a code like this

var fs = require('fs');
console.log("1");
fs.readFile("./index.js", function(err, data) {
    if (err) {
         console.log("err");
    }
    console.log("2");
});
console.log("3");

and the result will be

1
3
2

But I want 1 2 3 I have look through filesystem's document and it says With the asynchronous methods there is no guaranteed ordering.  so the document says if I want my code result 1 2 3 it should be

var fs = require('fs');
console.log("1");
fs.readFile("./index.js", function(err, data) {
    if (err) {
         console.log("err");
    }
    console.log("2");
    console.log("3");
});

But it's for short code if I'm building a system which has a lot of other function needs to be after this code we can't nested all in because the function need to be work after it will be use by other functions so is there a way to let the fs.readFile work in order but not incuding all the code need to work after it in fs code?

code I have issue

function servedatastart() {

    if (urlcontentbasic(urlslug) != "err") {
        responsearray["data"] = urlcontentbasic(urlslug);
    } else {
        // callback function
        console.log("urlex");
        urlex("none", urlslug); // this function I use fs.readFile(urlslug, function...
    }
    console.log("other function");
    //other function
    cuswriteheader();
    includescript();
    writefooter()
    res.end();
}

Body:
The simple solution is to just put the rest of your code that you want to execute after the fs.readFile() operation into a function and then insert that function into the async callback:

var fs = require('fs');
console.log("1");
fs.readFile("./index.js", function(err, data) {
    if (err) {
         console.log("err");
    }
    console.log("2");
    moreCode();
});

function moreCode() {
    console.log("3");
}

A bit more modern design is to use promises for all your asynchronous operations and then you can sequence things a bit easier.

const Promise = require('bluebird');
const fs = Promise.promisifyAll(require('fs'));

console.log("1");
fs.readFileAsync("./index.js").then((data) => {
    console.log("2");
    return moreCode();
}).catch((err) => {
    // handle error here
});

function moreCode() {
    console.log("3");
}

Where the benefit of using promises really starts to take advantage is when you have multiple asynchronous operations that you want to sequence and each one returns a promise.  Then, you can do that like this:

const Promise = require('bluebird');
const fs = Promise.promisifyAll(require('fs'));

fs.readFileAsync("./index.js")
  .then(moreCode1)
  .then(moreCode2)
  .catch((err) => {
      // handle error here
  });

Using the code you've show for the urlex() function, here's how you can make all that work using promises:

// include infrastructure to automatically promisify the fs module
const Promise = require('bluebird');
const fs = Promise.promisifyAll(require('fs'));

function servedatastart() {

    Promise.resolve().then(function() {
        if (urlcontentbasic(urlslug) != "err") {
            // I'm assuming that urlcontentbasic is also async and returns a promise
            // like urlexbasic does
            return urlcontentbasic(urlslug);
        } else {
            // callback function
            console.log("urlex");
            return urlex("none", urlslug);
        }
    }).then(function() {
        console.log("other function");
        //other function
        cuswriteheader();
        includescript();
        writefooter()
        res.end();
    });
}

// basic function for reading extension-less URL
// returns a promise whose resolved value is a returnarray data structure
function urlexbasic(filetype, slug) {
    var returnarray = {status:null,contenttype:null,data:null,message:undefined};
    if (slug == undefined) {
        slug = "";
    }

    if (filetype == "none") {
        var filename;
        console.log("path: "+pathdataarray["1"]);
        if (pathdataarray["1"] == "/pre") {
            console.log("substr");
            filename = urlslug.substr(4, urlslug.length-5);
            console.log("1: "+filename);
        }
        urldata(q.pathname, "");
        console.log("slug: "+ slug+" filename: "+ filename);
        if (slug != "" || filename != undefined) {
            console.log("what?")
            if (filename != undefined) {
                filename = "." + filename;
            } else {
                filename = "." + slug;
            }
            console.log("2: "+filename);
        } else {
            filename = "." + urlslug.substr(0, urlslug.length-1);
        }
        console.log("filename: "+ filename);
        return fs.readFileAsync(filename.substr(0, filename.length-1), 'utf8').then(function(data) {
            console.log("readfile");
            var mime = null;
            if (urldataarray.extension == "js") {
                mime = "javascript";
            } else {
                mime = urldataarray.extension;
            }
            console.log("hey running");
            returnarray["status"] = 200;
            returnarray["contenttype"] = 'text/'+mime;
            //res.writeHead(200, {'contenttype': 'text/'+mime});
            returnarray["data"] = data;
            console.log("instatus: "+returnarray["status"]);
            // make returnarray be the resolved value of the promise
            return returnarray;
        }).catch(function(err) {
            console.log("404 error");
            returnarray["status"] = 404;
        });
    } else {
        urldata(q.pathname, filetype);
        var filename;
        if (pathdataarray["1"] == "/pre") {
            console.log("substr");
            filename = urlslug.substr(4, urlslug.length-5);
            console.log("11: "+filename);
        }
        console.log("2slug: "+ slug+" filename: "+ filename);
        if (slug != "" || filename != undefined) {
            if (filename) {
                filename = "." + filename + "." + filetype;
            } else {
                filename = "." + slug +"."+ filetype;
            }
            console.log("22: "+filename);
        } else {
            filename = "." + urlslug.substr(0, urlslug.length-1) + "." + filetype;
        }
        return fs.readFileAsync(filename, 'utf8').then(function(data) {
            var mime = null;
            if (urldataarray.extension == "js") {
                mime = "javascript";
            } else {
                mime = urldataarray.extension;
                console.log("ok");
            };

            if (pathdataarray["1"] == "/pre") {
                returnarray["status"] = 200;
                returnarray["contenttype"] = 'text/plain';
                //res.writeHead(200, {'contenttype': 'text/plain'});
                //res.write("<pre><code>");
                returnarray["data"] = data;
                //res.write("</code></pre>");
            } else {
                returnarray["status"] = 200;
                returnarray["contenttype"] = 'text/'+mime;
                //res.writeHead(200, {'contenttype': 'text/'+mime});
                console.log("pure data");
                returnarray["data"] = data;
            }
            // make returnarray be the resolved value of the promise
            return returnArray;
        }).catch(function(err) {
            return urlex(dataerrcall[filetype]);
        });
    }
}

// returns a promise whose resolved value is a returnArray
function urlex(filetypeex, slugex) {
    //console.log(urlexbasic(filetypeex, slugex));
    return urlexbasic(filetypeex, slugex).then(function(returnArray) {
        console.log("return: "+returnarray.status);
        responsearray["status"] = returnarray["status"];

        responsearray["contenttype"] = returnarray["contenttype"]
        responsearray["message"] = returnarray["message"];
        responsearray["data"] = returnarray["data"];
        return responsearray;
    });
}

This uses several nice promise features such as chaining (to sequence async operations).


问:
Adding Claims to Identity from my WebApi
I am currently developing a Web Application that contains a Angular4 UI working with IdentitServer4 and a WebApi dotnetcore application.

We have the application authentication mechanism working with IDS but we now want to limit parts of our Angular application based on what permissions a user has granted them.  This information is stored behind our WebApi.  These permissions would also be used to secure our WebApi from stopping users doing particular actions if they aren't allowed i.e. EditUsers.

the problem I am facing is that ideally after being authentication by IdentityServer I would like the Angular application to fetch the list of allowed
permissions and from there they send those up to the WebApi as part of their claims.  The reason for this is that I don't want to have to query the database
on each Api Call if I can help it just to see if a particular user has access to a particular Controller action.

Is there anyway that I can set these claims so that subsequent calls to the API contains these and from there I can just check the claim information on the User Claim Identity
to verify access to a resource?

答:
You can add scope to your WebApi (official docs) for example

```<code>app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
{
    Authority = "https://demo.identityserver.io",
    ApiName = "api1",

    AllowedScopes = { "api1.read", "api1.write" }

    AutomaticAuthenticate = true,
    AutomaticChallenge = true
});
</code>```

And you can add claims to the client application as:

```<code>var mvcClient = new Client
{
    ClientId = "mvc",
    ClientName = "MVC Client",
    ClientUri = "http://identityserver.io",

    AllowedGrantTypes = GrantTypes.Hybrid,
    AllowOfflineAccess = true,
    ClientSecrets = { new Secret("secret".Sha256()) },

    RedirectUris =           { "http://localhost:5002/signin-oidc" },
    PostLogoutRedirectUris = { "http://localhost:5002/" },
    LogoutUri =                "http://localhost:5002/signout-oidc",

    AllowedScopes =
    {
        IdentityServerConstants.StandardScopes.OpenId,
        IdentityServerConstants.StandardScopes.Profile,
        IdentityServerConstants.StandardScopes.Email,

        "api1", "api2.read"
    },
};
</code>```

This is application base, for assigning permissions per user, you can define roles in your scopes for the user and can then decorate your controller or methods with that Role for ex:

```<code>For admin: new Claim("role","Admin")
For guestuser: new Claim("role","guest")

[HttpGet]
    [Authorize(Roles = "Admin")]
    public IActionResult Edit()
    {
        //whatever
    }

    [Authorize(Roles = "Guest")]
    [HttpGet]
    public IActionResult View()
    {
        //whatever
    }
</code>```

Body:
You can add scope to your WebApi (official docs) for example

app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
{
    Authority = "https://demo.identityserver.io",
    ApiName = "api1",

    AllowedScopes = { "api1.read", "api1.write" }

    AutomaticAuthenticate = true,
    AutomaticChallenge = true
});

And you can add claims to the client application as:

var mvcClient = new Client
{
    ClientId = "mvc",
    ClientName = "MVC Client",
    ClientUri = "http://identityserver.io",

    AllowedGrantTypes = GrantTypes.Hybrid,
    AllowOfflineAccess = true,
    ClientSecrets = { new Secret("secret".Sha256()) },

    RedirectUris =           { "http://localhost:5002/signin-oidc" },
    PostLogoutRedirectUris = { "http://localhost:5002/" },
    LogoutUri =                "http://localhost:5002/signout-oidc",

    AllowedScopes =
    {
        IdentityServerConstants.StandardScopes.OpenId,
        IdentityServerConstants.StandardScopes.Profile,
        IdentityServerConstants.StandardScopes.Email,

        "api1", "api2.read"
    },
};

This is application base, for assigning permissions per user, you can define roles in your scopes for the user and can then decorate your controller or methods with that Role for ex:

For admin: new Claim("role","Admin")
For guestuser: new Claim("role","guest")

[HttpGet]
    [Authorize(Roles = "Admin")]
    public IActionResult Edit()
    {
        //whatever
    }

    [Authorize(Roles = "Guest")]
    [HttpGet]
    public IActionResult View()
    {
        //whatever
    }


问:
How do I import a csv into chart.js?
I have been looking for this solution but can't seem to find it . Does chart.js support this ?

I have attempted to parse in the data with papaparse, but due to my limited knowledge I can't find a solution.

答:
I've had need to do something like this from time to time as well. Here's a link on how to create a chart with Chart.js from a CSV file that explains exactly how to create a chart with Chart.js directly from a CSV file.

The use case explains how to convert a CSV file to JSON using the Flex.io web service (Full disclosure: I'm the senior front end developer at Flex.io).

Here's a JsFiddle if you'd like to see the use case in action:

```<code>function getRandomColor() {
  var letters = '0123456789ABCDEF'.split('');
  var color = '#';
  for (var i = 0; i < 6; i++) {
    color += letters[Math.floor(Math.random() * 16)];
  }
  return color;
}

$.ajax({
  type: 'post',
  url: 'https://www.flex.io/api/v1/pipes/flexio-chart-js-csv-to-json/run?stream=0',
  beforeSend: function(xhr) {
    xhr.setRequestHeader('Authorization', 'Bearer nmgzsqppgwqbvkfhjdjd');
  },
  data: $('form').serialize(),
  dataType: "json",
  success: function(content) {
    // render the JSON result from from the Flex.io pipe
    $("#flexio-result-data").text(JSON.stringify(content, null, 2))

    var first_item = _.get(content, '[0]', {})

    var column_labels = _.map(_.omit(first_item, ['os']), function(val, key) {
      if (key != 'os')
        return key
    })

    // use Lodash to reformat the JSON for use with Chart.js
    var datasets = _.map(content, function(item) {
      // use the 'os' column as our label
      var item_label = _.get(item, 'os', 'Not Found')

      // create an array of number values from each item's JSON object
      var item_values = _.map(_.omit(item, ['os']), function(val) {
        return parseFloat(val)
      })

      return {
        label: item_label,
        data: item_values,
        backgroundColor: getRandomColor()
      }
    })

    var chart_data = {
      labels: column_labels,
      datasets: datasets
    }

    // render the JSON result after mapping the data with Lodash
    $("#chart-data").text(JSON.stringify(chart_data, null, 2))

    // render the chart using Chart.js
    var ctx = document.getElementById("canvas").getContext("2d");
    window.my_chart = new Chart(ctx, {
      type: 'bar',
      data: chart_data,
      options: {
        responsive: true,
        legend: {
          position: 'top'
        },
        title: {
          display: true,
          text: 'Use Flex.io to Create a Chart With Chart.js Directly From a CSV File'
        }
      }
    });
  }
});
</code>```

Feel free to step through the use case and let me know if you have any issues.

Title: How do I import a csv into chart.js?

Body:
I've had need to do something like this from time to time as well. Here's a link on how to create a chart with Chart.js from a CSV file that explains exactly how to create a chart with Chart.js directly from a CSV file.

The use case explains how to convert a CSV file to JSON using the Flex.io web service (Full disclosure: I'm the senior front end developer at Flex.io).

Here's a JsFiddle if you'd like to see the use case in action:

function getRandomColor() {
  var letters = '0123456789ABCDEF'.split('');
  var color = '#';
  for (var i = 0; i < 6; i++) {
    color += letters[Math.floor(Math.random() * 16)];
  }
  return color;
}

$.ajax({
  type: 'post',
  url: 'https://www.flex.io/api/v1/pipes/flexio-chart-js-csv-to-json/run?stream=0',
  beforeSend: function(xhr) {
    xhr.setRequestHeader('Authorization', 'Bearer nmgzsqppgwqbvkfhjdjd');
  },
  data: $('form').serialize(),
  dataType: "json",
  success: function(content) {
    // render the JSON result from from the Flex.io pipe
    $("#flexio-result-data").text(JSON.stringify(content, null, 2))

    var first_item = _.get(content, '[0]', {})

    var column_labels = _.map(_.omit(first_item, ['os']), function(val, key) {
      if (key != 'os')
        return key
    })

    // use Lodash to reformat the JSON for use with Chart.js
    var datasets = _.map(content, function(item) {
      // use the 'os' column as our label
      var item_label = _.get(item, 'os', 'Not Found')

      // create an array of number values from each item's JSON object
      var item_values = _.map(_.omit(item, ['os']), function(val) {
        return parseFloat(val)
      })

      return {
        label: item_label,
        data: item_values,
        backgroundColor: getRandomColor()
      }
    })

    var chart_data = {
      labels: column_labels,
      datasets: datasets
    }

    // render the JSON result after mapping the data with Lodash
    $("#chart-data").text(JSON.stringify(chart_data, null, 2))

    // render the chart using Chart.js
    var ctx = document.getElementById("canvas").getContext("2d");
    window.my_chart = new Chart(ctx, {
      type: 'bar',
      data: chart_data,
      options: {
        responsive: true,
        legend: {
          position: 'top'
        },
        title: {
          display: true,
          text: 'Use Flex.io to Create a Chart With Chart.js Directly From a CSV File'
        }
      }
    });
  }
});

Feel free to step through the use case and let me know if you have any issues.