问:
Traefik uses a certificate whithout chain after completing tls-alpn-01 challenge
I decided to switch from jwilder/nginx-proxy to traefik since I want to route to containers based on the URI-path which is not possible with jwilder/nginx-proxy but should be with traefik.

To do so I first wanted to transform my current setup (on single domain routed to one single container) that already used lets-encrypt.

My question is: How do I get traefik to give me the proper certificate signed by lets-encrypt instead of a self-signed thing?

So I have traefik in a docker container set up with acme.
I first tried to use HTTP-01-challenge without success but then decided to go with TLS-ALPN-01 anyhow.

After the startup of the container (and some waiting) the log finally reads (sensitive information replaced with Xs):

```<code>time="2019-05-30T20:01:25Z" level=info msg="legolog: [INFO] acme: Registering account for XXXXXXXX@XXXXXXXX.XXXXXXXX"
time="2019-05-30T20:01:25Z" level=info msg="legolog: [INFO] [XXXXXXXX.ddns.net] acme: Obtaining bundled SAN certificate"
time="2019-05-30T20:01:26Z" level=info msg="legolog: [INFO] [XXXXXXXX.ddns.net] AuthURL: https://acme-staging-v02.api.letsencrypt.org/acme/authz/XXXXXXXX"
time="2019-05-30T20:01:26Z" level=info msg="legolog: [INFO] [XXXXXXXX.ddns.net] acme: use tls-alpn-01 solver"
time="2019-05-30T20:01:26Z" level=info msg="legolog: [INFO] [XXXXXXXX.ddns.net] acme: Trying to solve TLS-ALPN-01"
time="2019-05-30T20:01:33Z" level=info msg="legolog: [INFO] [XXXXXXXX.ddns.net] The server validated our request"
time="2019-05-30T20:01:33Z" level=info msg="legolog: [INFO] [XXXXXXXX.ddns.net] acme: Validations succeeded; requesting certificates"
time="2019-05-30T20:02:17Z" level=info msg="legolog: [INFO] [XXXXXXXX.ddns.net] Server responded with a certificate."
</code>```

When navigating to the "AuthURL it reads (sensitive information again replaced with Xs):

```<code>{
"identifier": {
"type": "dns",
"value": "XXXXXXXX.ddns.net"
},
"status": "valid",
"expires": "2019-06-29T20:01:29Z",
"challenges": [
{
"type": "dns-01",
"status": "pending",
"url": "https://acme-staging-v02.api.letsencrypt.org/acme/challenge/XXXXXXXX/XXXXXXXX",
"token": "XXXXXXXX"
},
{
"type": "http-01",
"status": "pending",
"url": "https://acme-staging-v02.api.letsencrypt.org/acme/challenge/XXXXXXXX/XXXXXXXX",
"token": "XXXXXXXX"
},
{
"type": "tls-alpn-01",
"status": "valid",
"url": "https://acme-staging-v02.api.letsencrypt.org/acme/challenge/XXXXXXXX/XXXXXXXX",
"token": "XXXXXXXX",
"validationRecord": [
{
  "hostname": "XXXXXXXX.ddns.net",
  "port": "443",
  "addressesResolved": [
  "XXXXXXXX.XXXXXXXX.XXXXXXXX.XXXXXXXX"
  ],
  "addressUsed": "XXXXXXXX.XXXXXXXX.XXXXXXXX.XXXXXXXX"
}
]
}
]
}
</code>```

So everything had to be be fine I wrongly assumed.

When navigating to the traefik-frontend the certificate was issued for firefox show a certificate without a chain (like self-signed I suppose) which is naturally rejected (HTTP Strict Transport Security (HSTS), SEC_ERROR_UNKNOWN_ISSUER).

The domain of the certificate shows the correct domain I gave traefik for the frontend but the issuer reads "Fake LE Intermediate X1" which does not look like some lets-encrypt thing.
The saved acme.json (yes traefik configured with file store) has a certificate-entry (base64) which when decoded reveals two certificates.

Using https://www.sslshopper.com/certificate-decoder.html I found out that the first is the same certificate my browsers reject and the second has also "Fake LE Intermediate X1". Both do NOT look like the "TRAEFIK DEFAULT CERT" that you get when you try to get to the server via IP (not URL/domain) but that seems irrelevant.

I still have the certificates/keys from my previous setup where the issuer reads "Let's Encrypt Authority X3, Let's Encrypt Write review of Let's Encrypt". I could of course paste those in the acme.json wihtout knowing if that would work at all. But before to long the certificate expires anyway and I think I would face the same problem as I do now.

My traefik.toml looks like following:

```<code>logLevel = "INFO"
defaultEntryPoints = ["http", "https"]

################################################################
# API and dashboard configuration
################################################################
[api]
################################################################
# Docker configuration backend
dashboard = true
################################################################

#[web]
#address = ":8080"
#  [web.auth.basic]
#    users = ["admin:traefikW0rd"]

[docker]
domain = "XXXXXXXX.ddns.net"
watch = true
endpoint = "unix:///var/run/docker.sock"
exposedByDefault = false

[entryPoints]
  [entryPoints.http]
    address = ":80"
    [entryPoints.http.redirect]
      entryPoint = "https"
  [entryPoints.https]
    address = ":443"
      [entryPoints.https.tls]

[acme]
email = "XXXXXXXX@XXXXXXXX.XXXXXXXX"
storage = "/etc/traefik/ACME/acme.json"
keyType = "RSA4096"
caServer = "https://acme-staging-v02.api.letsencrypt.org/directory"
acmeLogging = true
entryPoint = "https"
#OnHostRule = true
  [acme.tlsChallenge]
  entryPoint = "https"

[[acme.domains]]
  main = "XXXXXXXX.ddns.net"
</code>```

答:
The samples I got for my traefik.toml pointed to a staging directory https://acme-staging-v02.api.letsencrypt.org/directory

This is also called "dry-run" in other applications.

I found this by googling for "Fake LE Intermediate X1".

After changing the variable to https://acme-v02.api.letsencrypt.org/directory and wiping acme.json I got usable certificates. \O/

Body:
I decided to switch from jwilder/nginx-proxy to traefik since I want to route to containers based on the URI-path which is not possible with jwilder/nginx-proxy but should be with traefik.

To do so I first wanted to transform my current setup (on single domain routed to one single container) that already used lets-encrypt.

My question is: How do I get traefik to give me the proper certificate signed by lets-encrypt instead of a self-signed thing?

So I have traefik in a docker container set up with acme.
I first tried to use HTTP-01-challenge without success but then decided to go with TLS-ALPN-01 anyhow.

After the startup of the container (and some waiting) the log finally reads (sensitive information replaced with Xs):

time="2019-05-30T20:01:25Z" level=info msg="legolog: [INFO] acme: Registering account for XXXXXXXX@XXXXXXXX.XXXXXXXX"
time="2019-05-30T20:01:25Z" level=info msg="legolog: [INFO] [XXXXXXXX.ddns.net] acme: Obtaining bundled SAN certificate"
time="2019-05-30T20:01:26Z" level=info msg="legolog: [INFO] [XXXXXXXX.ddns.net] AuthURL: https://acme-staging-v02.api.letsencrypt.org/acme/authz/XXXXXXXX"
time="2019-05-30T20:01:26Z" level=info msg="legolog: [INFO] [XXXXXXXX.ddns.net] acme: use tls-alpn-01 solver"
time="2019-05-30T20:01:26Z" level=info msg="legolog: [INFO] [XXXXXXXX.ddns.net] acme: Trying to solve TLS-ALPN-01"
time="2019-05-30T20:01:33Z" level=info msg="legolog: [INFO] [XXXXXXXX.ddns.net] The server validated our request"
time="2019-05-30T20:01:33Z" level=info msg="legolog: [INFO] [XXXXXXXX.ddns.net] acme: Validations succeeded; requesting certificates"
time="2019-05-30T20:02:17Z" level=info msg="legolog: [INFO] [XXXXXXXX.ddns.net] Server responded with a certificate."

When navigating to the "AuthURL it reads (sensitive information again replaced with Xs):

{
"identifier": {
"type": "dns",
"value": "XXXXXXXX.ddns.net"
},
"status": "valid",
"expires": "2019-06-29T20:01:29Z",
"challenges": [
{
"type": "dns-01",
"status": "pending",
"url": "https://acme-staging-v02.api.letsencrypt.org/acme/challenge/XXXXXXXX/XXXXXXXX",
"token": "XXXXXXXX"
},
{
"type": "http-01",
"status": "pending",
"url": "https://acme-staging-v02.api.letsencrypt.org/acme/challenge/XXXXXXXX/XXXXXXXX",
"token": "XXXXXXXX"
},
{
"type": "tls-alpn-01",
"status": "valid",
"url": "https://acme-staging-v02.api.letsencrypt.org/acme/challenge/XXXXXXXX/XXXXXXXX",
"token": "XXXXXXXX",
"validationRecord": [
{
  "hostname": "XXXXXXXX.ddns.net",
  "port": "443",
  "addressesResolved": [
  "XXXXXXXX.XXXXXXXX.XXXXXXXX.XXXXXXXX"
  ],
  "addressUsed": "XXXXXXXX.XXXXXXXX.XXXXXXXX.XXXXXXXX"
}
]
}
]
}

So everything had to be be fine I wrongly assumed.

When navigating to the traefik-frontend the certificate was issued for firefox show a certificate without a chain (like self-signed I suppose) which is naturally rejected (HTTP Strict Transport Security (HSTS), SEC_ERROR_UNKNOWN_ISSUER).

The domain of the certificate shows the correct domain I gave traefik for the frontend but the issuer reads "Fake LE Intermediate X1" which does not look like some lets-encrypt thing.
The saved acme.json (yes traefik configured with file store) has a certificate-entry (base64) which when decoded reveals two certificates.

Using https://www.sslshopper.com/certificate-decoder.html I found out that the first is the same certificate my browsers reject and the second has also "Fake LE Intermediate X1". Both do NOT look like the "TRAEFIK DEFAULT CERT" that you get when you try to get to the server via IP (not URL/domain) but that seems irrelevant.

I still have the certificates/keys from my previous setup where the issuer reads "Let's Encrypt Authority X3, Let's Encrypt Write review of Let's Encrypt". I could of course paste those in the acme.json wihtout knowing if that would work at all. But before to long the certificate expires anyway and I think I would face the same problem as I do now.

My traefik.toml looks like following:

logLevel = "INFO"
defaultEntryPoints = ["http", "https"]

################################################################
# API and dashboard configuration
################################################################
[api]
################################################################
# Docker configuration backend
dashboard = true
################################################################

#[web]
#address = ":8080"
#  [web.auth.basic]
#    users = ["admin:traefikW0rd"]

[docker]
domain = "XXXXXXXX.ddns.net"
watch = true
endpoint = "unix:///var/run/docker.sock"
exposedByDefault = false

[entryPoints]
  [entryPoints.http]
    address = ":80"
    [entryPoints.http.redirect]
      entryPoint = "https"
  [entryPoints.https]
    address = ":443"
      [entryPoints.https.tls]

[acme]
email = "XXXXXXXX@XXXXXXXX.XXXXXXXX"
storage = "/etc/traefik/ACME/acme.json"
keyType = "RSA4096"
caServer = "https://acme-staging-v02.api.letsencrypt.org/directory"
acmeLogging = true
entryPoint = "https"
#OnHostRule = true
  [acme.tlsChallenge]
  entryPoint = "https"

[[acme.domains]]
  main = "XXXXXXXX.ddns.net"


来源: stackexchange

问:
Display specific products on a CMS page
Could someone help me with some code to display specific products on a Magento CMS page?
The idea being that I build a page that has multiple sections on it (sections meaning a heading, some intro text and a small handful of products) and the user can add a selection of the displayed products to their cart from this page.

Ideally, the products should be displayed in the grid format, and I should be able to display between 1 and 6 products in each section.

I am using Magento 1.4.0.1 currently.

Cheers!

答:
Consider using a CMS Widget to do this for you.

Here is one: Product List Widget

It isn't free but there are others if you look around.

ContentLicense: CC BY-SA 3.0

Title: Display specific products on a CMS page


问:
Spark efficient groupby operation - repartition?
I'm working in pyspark 2.3 and I'm trying to figure out the most efficient way to get some aggregate statistics from a dataframe.

I have a dataframe with 1.5bn records spread out over a relatively small cluster of 10 nodes. Each has 16gb of ram and 4 cores. My replication factor is set to 2.

My dataframe has maybe 15 columns, which are a mixture of data types, but I'm only interested in two columns - ID and eventDate. The code I'd like to run is pretty simple:

```<code>output = df.groupby(['ID']).agg(F.min('eventDate').alias("firstDate"),F.max('eventDate').alias("lastDate"))
output.write.parquet('hdfs:///somewhere/dateFile.parquet',mode='overwrite')
</code>```

What I'm trying to figure out is the most efficient way to do this operation. ID, which is the field I'm grouping by, has 12m values, and df.rdd.getNumPartitions() is currently 642.

Am I better off first projecting my dataframe down to just the two columns I want? With so many IDs, should I repartition my dataset first? Should I drop duplicates? I could run something like this before my groupby:

```<code>df = df[['ID','eventDate']].drop_duplicates().repartition(x)
</code>```

or

```<code>df = df[['ID','eventDate']].repartition(x)
</code>```

I'm struggling a little bit to figure out what will optimize the run-time. Any guidance on predetermining run-time would be greatly appreciated. I'd prefer not to just "test it out" if possible because I have a couple of these queries to run, and each will take a while.

答:
It might not be an answer you were looking for, but the most optimal code for this operation is exactly

```<code>output = df.groupby(['ID']). \
 agg(F.min('eventDate').alias("firstDate"), F.max('eventDate').alias("lastDate"))
output.write.parquet('hdfs:///somewhere/dateFile.parquet', mode='overwrite')
</code>```

Spark optimises the process by only first selecting the necessary columns it needs for the entire operation. Afterwards Spark partitions your data by ID and starts the aggregation process on each partition.

Allowing max number of executors will definitely help. I'd suggest (based on your description) setting spark.executor.instances=10; spark.executor.memory=10g. 12m values is a fair amount, perhaps try boosting up the number of shuffle partitions, f.e. spark.sql.shuffle.partitions=400, just so that you won't get some annoying memory overhead exceptions.

ContentLicense: CC BY-SA 4.0

Body:
I'm working in pyspark 2.3 and I'm trying to figure out the most efficient way to get some aggregate statistics from a dataframe.

I have a dataframe with 1.5bn records spread out over a relatively small cluster of 10 nodes. Each has 16gb of ram and 4 cores. My replication factor is set to 2.

My dataframe has maybe 15 columns, which are a mixture of data types, but I'm only interested in two columns - ID and eventDate. The code I'd like to run is pretty simple:

output = df.groupby(['ID']).agg(F.min('eventDate').alias("firstDate"),F.max('eventDate').alias("lastDate"))
output.write.parquet('hdfs:///somewhere/dateFile.parquet',mode='overwrite')

What I'm trying to figure out is the most efficient way to do this operation. ID, which is the field I'm grouping by, has 12m values, and df.rdd.getNumPartitions() is currently 642.

Am I better off first projecting my dataframe down to just the two columns I want? With so many IDs, should I repartition my dataset first? Should I drop duplicates? I could run something like this before my groupby:

df = df[['ID','eventDate']].drop_duplicates().repartition(x)

or

df = df[['ID','eventDate']].repartition(x)

I'm struggling a little bit to figure out what will optimize the run-time. Any guidance on predetermining run-time would be greatly appreciated. I'd prefer not to just "test it out" if possible because I have a couple of these queries to run, and each will take a while.

Body:
It might not be an answer you were looking for, but the most optimal code for this operation is exactly

output = df.groupby(['ID']). \
 agg(F.min('eventDate').alias("firstDate"), F.max('eventDate').alias("lastDate"))
output.write.parquet('hdfs:///somewhere/dateFile.parquet', mode='overwrite')

Spark optimises the process by only first selecting the necessary columns it needs for the entire operation. Afterwards Spark partitions your data by ID and starts the aggregation process on each partition.

Allowing max number of executors will definitely help. I'd suggest (based on your description) setting spark.executor.instances=10; spark.executor.memory=10g. 12m values is a fair amount, perhaps try boosting up the number of shuffle partitions, f.e. spark.sql.shuffle.partitions=400, just so that you won't get some annoying memory overhead exceptions.


问:
Google Sheets Sumifs with date condition
I'm getting an error when trying to grab the money I have spent for a month on another Google Sheet using SUMIFS formula. I'm new to writing formulas and this is the first bottleneck I haven't been able to find.

I'm trying to write a formula in my google sheet but getting an error. I'm new at this so forgive me.

In the Google Sheet, I have three Sheets (Summary, which is main), Leads and Spend.

I'm trying to write a formula to grab how much I spent for a particular month. In the Spend sheet, I have column for the date, name and dollar amount.

Here is the formula I have tried without luck.

```<code>Spend!G:G = Column with text for type of spend (Google PPC)
Spend!E:E = Column with cost of each spend
Spend!A:A = Column with the date
</code>```

```<code>=SUMIFS(Spend!G:G,"Google PPC",Spend!E:E,Spend!A:A,">=1/1/2019", Spend!A:A,"<=1/31/2019")
</code>```

It should just give me a total amount spent on the dates given. But I get an error that says "array arguments to SUMIFS are of different size"

答:
a bit different approach would be:

```<code>=SUMPRODUCT(QUERY(Spend!A:G, "select E where year(A)=2019 and month(A)+1=1"))
</code>```

Body:
I'm getting an error when trying to grab the money I have spent for a month on another Google Sheet using SUMIFS formula. I'm new to writing formulas and this is the first bottleneck I haven't been able to find.

I'm trying to write a formula in my google sheet but getting an error. I'm new at this so forgive me.

In the Google Sheet, I have three Sheets (Summary, which is main), Leads and Spend.

I'm trying to write a formula to grab how much I spent for a particular month. In the Spend sheet, I have column for the date, name and dollar amount.

Here is the formula I have tried without luck.

Spend!G:G = Column with text for type of spend (Google PPC)
Spend!E:E = Column with cost of each spend
Spend!A:A = Column with the date

=SUMIFS(Spend!G:G,"Google PPC",Spend!E:E,Spend!A:A,">=1/1/2019", Spend!A:A,"<=1/31/2019")

It should just give me a total amount spent on the dates given. But I get an error that says "array arguments to SUMIFS are of different size"

Body:
a bit different approach would be:

=SUMPRODUCT(QUERY(Spend!A:G, "select E where year(A)=2019 and month(A)+1=1"))


问:
Vue oAuth staying logged in across express error
I am running an Express server on localhost:5000 and a Vue app on localhost:8080 with discord-passport oAuth2 login.

When I login and make a request in browser to localhost:5000/api/users It displays the correct information however when my Vue service handler makes the request the following error occurs data.map is not a function as the Express server checks if the user is authenticated and returns a string not logged in :(

My goal is to show the logged in users information on localhost:8080/#/profile.

I know the api works as it works in browser, I believe the issue is with the service handler.

This is api/users

```<code>const express = require('express');
const mongodb = require('mongodb');

const router = express.Router()

//get posts
router.get('/', checkAuth,async (req, res) => {
    const users = await loadUsersCollection()
    res.send(await users.find(req.user['id']).toArray());
})

function checkAuth(req, res, next) {
    if (req.isAuthenticated()) return next();
    console.log('not logged in')
    res.send('not logged in :(');
}

async function loadUsersCollection() {
    const client = await mongodb.MongoClient.connect('mongodb+srv://mongodbURI', {
        useNewUrlParser: true
    });
    return client.db('vue_express').collection('users');
}

module.exports = router;
</code>```

This is the service handler

```<code>import axios from 'axios'

const url = 'http://localhost:5000/api/users'

class UserService {
    // Get user
    static getUser() {
        return new Promise(async (resolve, reject) => {
            try {
                const res = await axios.get(url)
                const data = res.data;
                //if (data == 'not logged in :(')  throw 'not logged in'
                resolve(
                    data.map(user => ({
                         ...user,
                         createdAt: new Date(user.createdAt)
                     })
                    )

                )
            } catch (err) {
                reject(err)
            }
        })
    }
}

export default UserService
</code>```

and this is the Vue template

```<code><template>
  <div>
    User Page
    <p v-if="error">{{error}}</p>
    <button>Click</button>
    <div
      href="#"
      v-for="(user,index) in users"
      v-bind:item="user"
      v-bind:index="index"
      v-bind:key="user._id"
    >
      <p>Username: {{user.name}}</p>
      <p>{{user.email}}</p>
      <p>{{user.img}}</p>
      <p>{{user.type}}</p>
    </div>
  </div>
</template>

<script>
import UserService from "../UserService";

export default {
  name: "User",
  data() {
    return {
      users: [],
      error: "",
      name: "",
      email: "",
      img: "",
      type: "",
    };
  },
  async created() {
    try {
      this.users = await UserService.getUser();
    } catch (err) {
      this.error = err.message;
    }
  }
};
</script>
</code>```

答: The cookie is not being set by the passport-discord npm module.</p>

Body:
I am running an Express server on localhost:5000 and a Vue app on localhost:8080 with discord-passport oAuth2 login.

When I login and make a request in browser to localhost:5000/api/users It displays the correct information however when my Vue service handler makes the request the following error occurs data.map is not a function as the Express server checks if the user is authenticated and returns a string not logged in :(

My goal is to show the logged in users information on localhost:8080/#/profile.

I know the api works as it works in browser, I believe the issue is with the service handler.

This is api/users

const express = require('express');
const mongodb = require('mongodb');

const router = express.Router()

//get posts
router.get('/', checkAuth,async (req, res) => {
    const users = await loadUsersCollection()
    res.send(await users.find(req.user['id']).toArray());
})

function checkAuth(req, res, next) {
    if (req.isAuthenticated()) return next();
    console.log('not logged in')
    res.send('not logged in :(');
}

async function loadUsersCollection() {
    const client = await mongodb.MongoClient.connect('mongodb+srv://mongodbURI', {
        useNewUrlParser: true
    });
    return client.db('vue_express').collection('users');
}

module.exports = router;

This is the service handler

import axios from 'axios'

const url = 'http://localhost:5000/api/users'

class UserService {
    // Get user
    static getUser() {
        return new Promise(async (resolve, reject) => {
            try {
                const res = await axios.get(url)
                const data = res.data;
                //if (data == 'not logged in :(')  throw 'not logged in'
                resolve(
                    data.map(user => ({
                         ...user,
                         createdAt: new Date(user.createdAt)
                     })
                    )

                )
            } catch (err) {
                reject(err)
            }
        })
    }
}

export default UserService

and this is the Vue template

<template>

    User Page

{{error}}

    <button>Click</button>

Username: {{user.name}}

{{user.email}}

{{user.img}}

{{user.type}}

</template>


问:
Return Count Value back as 0 if emtpy or none
I am running the following query in our database and I am trying to get the count value back as 0 if none are present, but having problems doing so. Could someone help assist and explain how to accomplish this

```<code>select state, count(phone_number) from VOIP_PHONE_NUMBER_POOL
where status = 3
group by state
order by state asc;
</code>```

For example, currently my query is returning something back like this

```<code>State  Count

AZ     25
</code>```

When I want it to return the empty values and look like this

```<code>State  Count

AZ     25
CA     0
</code>```

答:
```<code>     SELECT s.state,
            COUNT(v.phone_number) AS phone_number_count
       FROM CORP_ACCT s
       LEFT OUTER JOIN voip_phone_number_pool v
            ON s.state = v.state
   GROUP BY s.state;
</code>```

worked for me

Body:
I am running the following query in our database and I am trying to get the count value back as 0 if none are present, but having problems doing so. Could someone help assist and explain how to accomplish this

select state, count(phone_number) from VOIP_PHONE_NUMBER_POOL
where status = 3
group by state
order by state asc;

For example, currently my query is returning something back like this

State  Count

AZ     25

When I want it to return the empty values and look like this

State  Count

AZ     25
CA     0

Body:
     SELECT s.state,
            COUNT(v.phone_number) AS phone_number_count
       FROM CORP_ACCT s
       LEFT OUTER JOIN voip_phone_number_pool v
            ON s.state = v.state
   GROUP BY s.state;

worked for me


问:
Query Sorting in firebase Swift
My realtime-database is structured like this:

```<code>   - Procedure001
        - Post0001
            - user_id: 00001
            - timestamp: 1559214445
</code>```

I would like to read the database and get only the posts that user0001 posted, and also sort them by most recent post (by timestamp).

Currently I am able to get only the posts by a certain user like so -

```<code>let ref = Database.database().reference().child("Procedure001").queryOrdered(byChild: "user_id").queryEqual(toValue: "0001")
</code>```

How can I also sort the by timestamp using firebase?

答:
I realize you posted an answer and while it will work, there are some limitations.

If the user posts a million posts, trying to load all of those in and sort in code may overwhelm the device. even if it's a smaller amount of nodes, it's much faster to have Firebase do the sort and present the data than having your app process through it all.

So often times you will find the solution is to duplicate the data depending on the types of queries you want to run. In this case you have a node that stores the user id and time stamp of each post

```<code>Procedure
   post_0
      uid: uid_0
      timestamp: 20190529
   post 1
      uid: uid_0
      timestamps: 20190530
</code>```

As you mentioned you can query for all posts from uid_0 and sort by timestamp in code. But, check this out...

```<code>user_posts
   uid_0
      post_0: 20190529
      post_1: 20190530
</code>```

By adding an additional node that keeps track of the user posts the query can be eliminated since all of the posts are stored in one place, and can be easily sorted on the server.

I'll throw one other option out, compound values.

```<code>Procedure
   post_0:
      uid_timestamp: uid_0_20190529
   post_1:
      uid_timestamp: uid_0_20190530
</code>```

Using this structure, you can query for all uid_0's posts, ordered by uid_timestamp.

Title: Query Sorting in firebase Swift

Body:
My realtime-database is structured like this:

   - Procedure001
        - Post0001
            - user_id: 00001
            - timestamp: 1559214445

I would like to read the database and get only the posts that user0001 posted, and also sort them by most recent post (by timestamp).

Currently I am able to get only the posts by a certain user like so -

let ref = Database.database().reference().child("Procedure001").queryOrdered(byChild: "user_id").queryEqual(toValue: "0001")

How can I also sort the by timestamp using firebase?

Body:
I realize you posted an answer and while it will work, there are some limitations.

If the user posts a million posts, trying to load all of those in and sort in code may overwhelm the device. even if it's a smaller amount of nodes, it's much faster to have Firebase do the sort and present the data than having your app process through it all.

So often times you will find the solution is to duplicate the data depending on the types of queries you want to run. In this case you have a node that stores the user id and time stamp of each post

Procedure
   post_0
      uid: uid_0
      timestamp: 20190529
   post 1
      uid: uid_0
      timestamps: 20190530

As you mentioned you can query for all posts from uid_0 and sort by timestamp in code. But, check this out...

user_posts
   uid_0
      post_0: 20190529
      post_1: 20190530

By adding an additional node that keeps track of the user posts the query can be eliminated since all of the posts are stored in one place, and can be easily sorted on the server.

I'll throw one other option out, compound values.

Procedure
   post_0:
      uid_timestamp: uid_0_20190529
   post_1:
      uid_timestamp: uid_0_20190530

Using this structure, you can query for all uid_0's posts, ordered by uid_timestamp.


问:
i would like to read by clicking the text id
I am new to jQuery and need help for the following problem.

How can I read the text from div and print in alert at click function?

My html code:

```<code><div>
  <div id"test">text1</div>
  <a href="#">select</a>

   <div id"test">text2</div>
   <a href="#">select</a>

   <div id"test">text3</div>
   <a href="#">select</a>
</div>
</code>```

答:
$('a').on('click', function() {
  var div = $(this).prev();
  alert(div.text());
});```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
  <div id="test1">text1</div> select
  <div id="test2">text2</div> select
  <div id="test3">text3</div> select
</div></code>```

Body:
I am new to jQuery and need help for the following problem.

How can I read the text from div and print in alert at click function?

My html code:

text1

  select

text2

   select

text3

   select

Body:
$('a').on('click', function() {
  var div = $(this).prev();
  alert(div.text());
});

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
  <div id="test1">text1</div> <a href="#">select</a>
  <div id="test2">text2</div> <a href="#">select</a>
  <div id="test3">text3</div> <a href="#">select</a>
</div>


问:
iOS: disable bounce scroll but allow normal scrolling
I don't want the content of my site sloshing around when the user hits the edge of a page. I just want it to stop.

The omni-present javascript solution I see everywhere is this:

```<code>$(document).bind(
   'touchmove',
   function(e) {
     e.preventDefault();
   }
);
</code>```

But this prevents scrolling entirely. Is there way to just remove the bounce. Preferably with CSS or a meta tag as opposed JS, but anything that works will do.

答: After trying these suggestions and reading several articles, the fix for me was to use the CSS property < overflow-x: hidden; > on the problematic element/container.</p>

Body:
I don't want the content of my site sloshing around when the user hits the edge of a page. I just want it to stop.

The omni-present javascript solution I see everywhere is this:

$(document).bind(
   'touchmove',
   function(e) {
     e.preventDefault();
   }
);

But this prevents scrolling entirely. Is there way to just remove the bounce. Preferably with CSS or a meta tag as opposed JS, but anything that works will do.


问:
Add User to Azure Active Directory using https://graph.microsoft.com with ActiveDirectoryClient
I'm trying to add a user to my Azure tenant's Active Directory.

I'm using Microsoft Graph API. The same one exposed through Graph Explorer here.

The problem is that no matter what serviceRoot URI I pass, I'm getting an exception.

I successfully get a token in GetTokenForApplication method:

```<code>ActiveDirectoryClient activeDirectoryClient = new ActiveDirectoryClient(serviceRoot,
                      async () => await GetTokenForApplication());
</code>```

However, when I call:

```<code>await activeDirectoryClient.Users.AddUserAsync(aadUser);
</code>```

It throws this exception:

```<code> "{\r\n
    \"error\": {\r\n
                   \"code\": \"BadRequest\",\r\n
                   \"message\": \"Query parameter api-version not allowed\",\r\n
                   \"innerError\": {\r\n
                                    \"request-id\": \"57327a85-8320-4363-b5f9-aeacdf782861\",\r\n
                                    \"date\": \"2019-05-30T21:59:55\"\r\n
                                   }\r\n
               }\r\n
}"
</code>```

This is the serviceRoot URI I'm using: "https://graph.microsoft.com/v1.0"

What URI should I pass in serviceRoot?

Is ActiveDirectoryClient compatible with Microsoft Graph? I ask because the sample where I saw ActiveDirectoryClient being used was using Azure AD Graph API.

This blog post shows the difference between the old Azure AD Graph API and the new Microsoft Graph API. By the way: Microsoft advises us to use Microsoft Graph API because all new development is going to be concentrated on it.

答:
I think you are trying to use the newer Microsoft Graph API (https://graph.microsoft.com) but using the client library for older Azure AD Graph API (https://graph.windows.net)

You can read about the comparison in detail here - Microsoft Graph or the Azure AD Graph

Here are nuget package and class details:

Microsoft Graph API

Microsoft.Graph nuget package - to work with Microsoft Graph API and use GraphServiceClient class.

Azure AD Graph API

Microsoft.Azure.ActiveDirectory.GraphClient nuget package - to work with Azure AD Graph API and use ActiveDirectoryClient class.

Code for Microsoft Graph API Client

Microsoft Docs - Create User - SDK Sample Code

```<code>GraphServiceClient graphClient = new GraphServiceClient( authProvider );

var user = new User
{
    AccountEnabled = true,
    DisplayName = "displayName-value",
    MailNickname = "mailNickname-value",
    UserPrincipalName = "upn-value@tenant-value.onmicrosoft.com",
    PasswordProfile = new PasswordProfile
    {
        ForceChangePasswordNextSignIn = true,
        Password = "password-value"
    }
};

await graphClient.Users
    .Request()
    .AddAsync(user);
</code>```

Body:
I'm trying to add a user to my Azure tenant's Active Directory.

I'm using Microsoft Graph API. The same one exposed through Graph Explorer here.

The problem is that no matter what serviceRoot URI I pass, I'm getting an exception.

I successfully get a token in GetTokenForApplication method:

ActiveDirectoryClient activeDirectoryClient = new ActiveDirectoryClient(serviceRoot,
                      async () => await GetTokenForApplication());

However, when I call:

await activeDirectoryClient.Users.AddUserAsync(aadUser);

It throws this exception:

 "{\r\n
    \"error\": {\r\n
                   \"code\": \"BadRequest\",\r\n
                   \"message\": \"Query parameter api-version not allowed\",\r\n
                   \"innerError\": {\r\n
                                    \"request-id\": \"57327a85-8320-4363-b5f9-aeacdf782861\",\r\n
                                    \"date\": \"2019-05-30T21:59:55\"\r\n
                                   }\r\n
               }\r\n
}"

This is the serviceRoot URI I'm using: "https://graph.microsoft.com/v1.0"

What URI should I pass in serviceRoot?

Is ActiveDirectoryClient compatible with Microsoft Graph? I ask because the sample where I saw ActiveDirectoryClient being used was using Azure AD Graph API.

This blog post shows the difference between the old Azure AD Graph API and the new Microsoft Graph API. By the way: Microsoft advises us to use Microsoft Graph API because all new development is going to be concentrated on it.

Body:
I think you are trying to use the newer Microsoft Graph API (https://graph.microsoft.com) but using the client library for older Azure AD Graph API (https://graph.windows.net)

You can read about the comparison in detail here - Microsoft Graph or the Azure AD Graph

Here are nuget package and class details:

Microsoft Graph API

Microsoft.Graph nuget package - to work with Microsoft Graph API and use GraphServiceClient class.

Azure AD Graph API

Microsoft.Azure.ActiveDirectory.GraphClient nuget package - to work with Azure AD Graph API and use ActiveDirectoryClient class.

Code for Microsoft Graph API Client

Microsoft Docs - Create User - SDK Sample Code

GraphServiceClient graphClient = new GraphServiceClient( authProvider );

var user = new User
{
    AccountEnabled = true,
    DisplayName = "displayName-value",
    MailNickname = "mailNickname-value",
    UserPrincipalName = "upn-value@tenant-value.onmicrosoft.com",
    PasswordProfile = new PasswordProfile
    {
        ForceChangePasswordNextSignIn = true,
        Password = "password-value"
    }
};

await graphClient.Users
    .Request()
    .AddAsync(user);


问:
2x one-to-many relationships in OO
Imagine these relationships:

1 A has many B's

1 B has many C's...

In reverse:

C has 1 B

B has 1A

By transitivity, C has 1 A

To model this relationship in DB, we have:

```<code>TableA
a_id

TableB
b_id
a_id (fk to TableA)

TableC
c_id
b_id (fk to TableB)
</code>```

To model this relationship in OO, we have:

```<code>objA
objB
objC
</code>```

And...
- objB has reference to objA
- objC has reference to objB

If objC has a method that needs to call a method of objA, what will you do?

Option 1.

```<code>b.getA().runMethodX()
</code>```

Many ppl I know would do this, but I've also learned that this is not good because getA() is not a behavior of B in a pure OO sense.  Doing so is just like doing procedural programming.  Agree/Disagree?

Option 2.

Let objC has direct reference to objA and objB through constructor injection / setter

Is this a good idea?  but then objB that objC has reference to also has reference to objA.  Is this okay?  Or as long as it is not a case of cyclic object references, it is acceptable?

Option 3.

Move the method in question to objA, and pass objC in by parameter.

I'm not sure if this considers as an option.  I think it'll not work in every case.  Have the method in objC reduce to bare minimum that only works on its states, and let objA do whatever objA needs to do before or after.

Option 4.  (Delegation)

add runMethodXinA() to B, it calls

```<code>a.runMethodX()
</code>```

C calls

```<code>b.runMethodXinA()
</code>```

I tried this method before, but B will very likely end up having as many methods as A, and doesn't having 1 method in both B and A violates DRY?

What are your though?  Any other options?  Comments?  Suggestions?

答:
Option 2 is a fairly dangerous duplication of information, in addition to whatever issues may come out of the shape of the reference graph depending on your environment.

Option 3 might make sense if the method is in some sense dependent on the type of objA, as a sort of double dispatch.

Option 1 goes against the Law of Demeter, but it sounds like it's the least intrusive option.

You may also want to consider a forwarding method on objB that passes the call to objA.

OwnerDisplayName: Henry

Title: 2x one-to-many relationships in OO

Body:
Imagine these relationships:

1 A has many B's

1 B has many C's...

In reverse:

C has 1 B

B has 1A

By transitivity, C has 1 A

To model this relationship in DB, we have:

TableA
a_id

TableB
b_id
a_id (fk to TableA)

TableC
c_id
b_id (fk to TableB)

To model this relationship in OO, we have:

objA
objB
objC

And...
- objB has reference to objA
- objC has reference to objB

If objC has a method that needs to call a method of objA, what will you do?

Option 1.

b.getA().runMethodX()

Many ppl I know would do this, but I've also learned that this is not good because getA() is not a behavior of B in a pure OO sense.  Doing so is just like doing procedural programming.  Agree/Disagree?

Option 2.

Let objC has direct reference to objA and objB through constructor injection / setter

Is this a good idea?  but then objB that objC has reference to also has reference to objA.  Is this okay?  Or as long as it is not a case of cyclic object references, it is acceptable?

Option 3.

Move the method in question to objA, and pass objC in by parameter.

I'm not sure if this considers as an option.  I think it'll not work in every case.  Have the method in objC reduce to bare minimum that only works on its states, and let objA do whatever objA needs to do before or after.

Option 4.  (Delegation)

add runMethodXinA() to B, it calls

a.runMethodX()

C calls

b.runMethodXinA()

I tried this method before, but B will very likely end up having as many methods as A, and doesn't having 1 method in both B and A violates DRY?

What are your though?  Any other options?  Comments?  Suggestions?

LastEditorDisplayName: cletus

OwnerDisplayName: Jeffrey Hantin

ContentLicense: CC BY-SA 2.5


问:
Skip login screen in case user is already logged in
I'm using firebase to authenticate my user. I created some activities and have login screen which I want to show if user is not logged in already. I defined most of activities in manifest as default, and login screen activity as main. Am I doing it properly? Which of screens should be defined in manifest as main? Login screen or screen with most of informations (right main)?</p>

答:
i think you should use a splash screen as main , its's normally used to display some kind of progress before the application setup completely

```<code>public class SplashActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null) {
    // User is signed in
    // Start home activity
    startActivity(new Intent(SplashActivity.this, HomeActivity.class));
    } else {
    // No user is signed in
    // start login activity
    startActivity(new Intent(SplashActivity.this, loginActivity.class));
    }

    // close splash activity
    finish();
 }
}
</code>```

and to know if the user is already logged in as  mentioned in the official documentation :

The recommended way to get the current user is by calling the getCurrentUser method. If no user is signed in, getCurrentUser returns null

```<code>FirebaseAuth.getInstance().getCurrentUser()
</code>```

It should return null if a user is not logged in.

Body:
i think you should use a splash screen as main , its's normally used to display some kind of progress before the application setup completely

public class SplashActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null) {
    // User is signed in
    // Start home activity
    startActivity(new Intent(SplashActivity.this, HomeActivity.class));
    } else {
    // No user is signed in
    // start login activity
    startActivity(new Intent(SplashActivity.this, loginActivity.class));
    }

    // close splash activity
    finish();
 }
}

and to know if the user is already logged in as  mentioned in the official documentation :

The recommended way to get the current user is by calling the getCurrentUser method. If no user is signed in, getCurrentUser returns null

FirebaseAuth.getInstance().getCurrentUser()

It should return null if a user is not logged in.


问:
Having trouble to complete Unittest class based views in DJANGO
How can I complete this views unittest with django?
I am getting started with unittest and for some reason i am not able to complete the first class based views test successfully.

models.py

```<code>class BookListView(ListView):
    model = Book
    context_object_name = 'books'
    template_name = 'snippets/list.html'

</code>```

urls.py

```<code>from django.contrib import admin
from django.urls import path, include
from .views import (BookListView)
from . import views

app_name = 'snippets'
urlpatterns = [
    path('', views.index, name='book_list'),
</code>```

views.py

```<code>from django.test import TestCase, Client
from django.urls import reverse
from snippets.models import Book
import json

class TestViews(TestCase):

    def setUp(self):
        self.client = Client()

    def test_book_list_GET(self):
        response = self.client.get(reverse('snippets:book_list'))
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'snippets/list.html')

</code>```

Below is the feedback crashing from the terminal

```<code>self.assertEqual(response.status_code, 200)
AssertionError: 404 != 200

----------------------------------------------------------------------
Ran 1 test in 0.061s

FAILED (failures=1)
Destroying test database for alias 'default'...
</code>```

答:
As already commented:

```<code>class TestViews(TestCase):

    def setUp(self):
        self.client = Client()

    def test_book_list_GET(self):
        response = self.client.get('snippets:book_list')
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'snippets/list.html')
</code>```

you need to pass the url here, with django.urls.utils.reverse which would give you the relative url for the view

Body:
How can I complete this views unittest with django?
I am getting started with unittest and for some reason i am not able to complete the first class based views test successfully.

models.py

class BookListView(ListView):
    model = Book
    context_object_name = 'books'
    template_name = 'snippets/list.html'

urls.py

from django.contrib import admin
from django.urls import path, include
from .views import (BookListView)
from . import views

app_name = 'snippets'
urlpatterns = [
    path('', views.index, name='book_list'),

views.py

from django.test import TestCase, Client
from django.urls import reverse
from snippets.models import Book
import json

class TestViews(TestCase):

    def setUp(self):
        self.client = Client()

    def test_book_list_GET(self):
        response = self.client.get(reverse('snippets:book_list'))
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'snippets/list.html')

Below is the feedback crashing from the terminal

self.assertEqual(response.status_code, 200)
AssertionError: 404 != 200

----------------------------------------------------------------------
Ran 1 test in 0.061s

FAILED (failures=1)
Destroying test database for alias 'default'...

Body:
As already commented:

class TestViews(TestCase):

    def setUp(self):
        self.client = Client()

    def test_book_list_GET(self):
        response = self.client.get('snippets:book_list')
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'snippets/list.html')

you need to pass the url here, with django.urls.utils.reverse which would give you the relative url for the view


问:
Updating first 7 characters of string with another 3 characters using SQL, throws "Error 19 - UNIQUE constraint failed: MGOFile.File."
I have a rather simple DB with a column called File, and I need to remove the first 7 characters of each row, and replace with a new string. I thought I had the code sorted, but I am getting error "SQLite3 Error 19 - UNIQUE constraint failed: MGOFile.File."

My table name is MGOFile, and the column is File. This is a simple select statement on the first few rows, the left column is the raw data, the right is what I need the resultant rows to look like...

I query my table using this:

```<code>    '''sql
    SELECT
      File,
      'T:\'|| substr(File, 8,2000) as File
    FROM
      MGOFile
    WHERE
      file like 'M:\_TV%';
    '''
</code>```

I then tried updating using this:

```<code>    UPDATE MGOFile
    SET File = 'T:\' || substr(File, 8, 2000)
    WHERE File like 'M:\_TV%';
</code>```

But here is where my error comes in, this fails with an error:

I am sure I am doing something simple wrong, but I have done plenty of Googling but all responses are over my head, this is the most advanced SQL I have tried to do!

Any ideas on how to can update these strings with some simple SQLite?

答:
As checking for duplicates doesn't appear to detect the issues. Perhaps getting values at the time of the issue may assist. Do you have Triggers by any-chance? These will sometimes propagate an error which will be reported as being with the table that triggered the trigger.

As such perhaps consider adding a table to log such data along with a BEFORE UPDATE TRIGGER to actually log the information at run time. To stop the data being rolled back and thus undoing the logged information OR FAIL needs to be used.

Important as the updates will not be rolled back updates will have been applied. It is suggested that the above is used on a test database.

```<code>-- The code
DROP TABLE IF EXISTS lastupdated;
-- Create the logging table
CREATE TABLE IF NOT EXISTS lastupdated (counter, lastfile_before, lastfile_after, id_of_the_row);
-- Initialise it so it's plain to see if nothing has been done
INSERT INTO lastupdated VALUES(0,'nothing','nothing',0);

-- Add the Trigger to record the debugging information BEFORE the update
CREATE TRIGGER IF NOT EXISTS monitorupdateprogress
    BEFORE UPDATE ON MGOFile
    BEGIN
        UPDATE lastupdated SET counter = counter +1, lastfile_before = old.File, lastfile_after = new.File, id_of_the_row = old.rowid;
    END
;
UPDATE OR FAIL MGOFile -- OR FAIL will halt but NOT ROLLBACK
    SET File = 'T:\' || substr(File, 8, 2000)
    WHERE File like 'M:\_TV%';
SELECT * FROM lastupdated; -- will not run if there is a fail but should be run after the fail
</code>```

This would, assuming the fail, record

the nth update in the counter column

the value in the File column before the change  in the lastfile_before column.

the value that the File column would be updated to in the **lastfile_after* columns.

the last rowid (failing) of the row in the MGOFile table (this does assume that the MGOFile table is not a table defined using WITHOUT ROWID).

If the table was defined with the WITHOUT ROWID then you could change , id_of_the_row = 0;. The value will then be meaningless.

Testing/Results the version of the above that was used to test the above is :-

```<code>-- Solely for testing the code below
DROP TABLE IF EXISTS MGOFile;
CREATE TABLE IF NOT EXISTS MGOFile (File TEXT PRIMARY KEY);

-- Some testing data
INSERT INTO MGOFile VALUES
    ('M:\_TV/9-1-1.so2e09.web.x264-tbs[eztv].mkv'),
    ('M:\_TV/9-1-1.so2e09.web.x265-tbs[eztv].mkv'),
    ('M:\_TV/9-1-1.so2e09.web.x266-tbs[eztv].mkv'),
    ('M:\_TV/9-1-1.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv'),
    ('M:\_TV/9-1-1.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x277-tbs[eztv].mkv'),
    ('M:\_TV/9-1-1.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x278-tbs[eztv].mkv'),
    ('M:\_TV/9-1-1.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x279-tbs[eztv].mkv'),
    ('M:\_TV/9-1-1.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x280-tbs[eztv].mkv')
;

SELECT substr(File,170,8) FROM MGOFile GROUP BY Substr(File,8,170) HAVING count() > 1;

-- The code
DROP TABLE IF EXISTS lastupdated;
-- Create the logging table
CREATE TABLE IF NOT EXISTS lastupdated (counter, lastfile_before, lastfile_after, id_of_the_row);
-- Initialise it so it's plain to see if nothing has been done
INSERT INTO lastupdated VALUES(0,'nothing','nothing',0);
-- Add the Trigger to record the debugging information BEFORE the update
CREATE TRIGGER IF NOT EXISTS monitorupdateprogress
    BEFORE UPDATE ON MGOFile
    BEGIN
        UPDATE lastupdated SET counter = counter +1, lastfile_before = old.File, lastfile_after = new.File, id_of_the_row = old.rowid;
    END
;
SELECT * FROM MGOFile;
UPDATE OR FAIL MGOFile -- OR FAIL will halt but NOT ROLLBACK
    SET File = 'T:\' || substr(File, 8, 170) -- <<<<<<<<<<<<<<<<<<<< truncate reduced to force UNIQUE constraint
    WHERE File like 'M:\_TV%';
SELECT * FROM lastupdated; -- will not run if there is a fail
</code>```

When the above is run then the message is :-

```<code>UPDATE OR FAIL MGOFile -- OR FAIL will halt but NOT ROLLBACK
    SET File = 'T:\' || substr(File, 8, 170) -- <<<<<<<<<<<<<<<<<<<< truncate reduced to force UNIQUE constraint
    WHERE File like 'M:\_TV%'
> UNIQUE constraint failed: MGOFile.File
> Time: 0.094s
</code>```

Running SELECT * FROM lastupdated; returns :-

counter

6

lastfile_before   =

M:_TV/9-1-1.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x278-tbs[eztv].mkv

lastfile_after

T:\9-1-1.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x27

id_of_the_row

6

In the above contrived example the issue can easily be determined (albeit that the duplicate search also found the same issue) as the error is on the 6th row and at the row that contains mkv.so2e09.web.x278-tbs[eztv] but was truncated by the update to .mkv.so2e09.web.x27 hence it is a duplicate of the 5th row which has .mkv.so2e09.web.x277-tbs[eztv] but was also truncated to .mkv.so2e09.web.x27.

P.S. Have you tried using just

```<code>UPDATE MGOFile
SET File = 'T:\' || substr(File, 8)
WHERE File like 'M:\_TV%';
</code>```

i.e. removing the truncation.

Body:
I have a rather simple DB with a column called File, and I need to remove the first 7 characters of each row, and replace with a new string. I thought I had the code sorted, but I am getting error "SQLite3 Error 19 - UNIQUE constraint failed: MGOFile.File."

My table name is MGOFile, and the column is File. This is a simple select statement on the first few rows, the left column is the raw data, the right is what I need the resultant rows to look like...

I query my table using this:

    '''sql
    SELECT
      File,
      'T:\'|| substr(File, 8,2000) as File
    FROM
      MGOFile
    WHERE
      file like 'M:\_TV%';
    '''

I then tried updating using this:

    UPDATE MGOFile
    SET File = 'T:\' || substr(File, 8, 2000)
    WHERE File like 'M:\_TV%';

But here is where my error comes in, this fails with an error:

I am sure I am doing something simple wrong, but I have done plenty of Googling but all responses are over my head, this is the most advanced SQL I have tried to do!

Any ideas on how to can update these strings with some simple SQLite?

Body:
As checking for duplicates doesn't appear to detect the issues. Perhaps getting values at the time of the issue may assist. Do you have Triggers by any-chance? These will sometimes propagate an error which will be reported as being with the table that triggered the trigger.

As such perhaps consider adding a table to log such data along with a BEFORE UPDATE TRIGGER to actually log the information at run time. To stop the data being rolled back and thus undoing the logged information OR FAIL needs to be used.

Important as the updates will not be rolled back updates will have been applied. It is suggested that the above is used on a test database.

-- The code
DROP TABLE IF EXISTS lastupdated;
-- Create the logging table
CREATE TABLE IF NOT EXISTS lastupdated (counter, lastfile_before, lastfile_after, id_of_the_row);
-- Initialise it so it's plain to see if nothing has been done
INSERT INTO lastupdated VALUES(0,'nothing','nothing',0);

-- Add the Trigger to record the debugging information BEFORE the update
CREATE TRIGGER IF NOT EXISTS monitorupdateprogress
    BEFORE UPDATE ON MGOFile
    BEGIN
        UPDATE lastupdated SET counter = counter +1, lastfile_before = old.File, lastfile_after = new.File, id_of_the_row = old.rowid;
    END
;
UPDATE OR FAIL MGOFile -- OR FAIL will halt but NOT ROLLBACK
    SET File = 'T:\' || substr(File, 8, 2000)
    WHERE File like 'M:\_TV%';
SELECT * FROM lastupdated; -- will not run if there is a fail but should be run after the fail

This would, assuming the fail, record

the nth update in the counter column

the value in the File column before the change  in the lastfile_before column.

the value that the File column would be updated to in the **lastfile_after* columns.

the last rowid (failing) of the row in the MGOFile table (this does assume that the MGOFile table is not a table defined using WITHOUT ROWID).

If the table was defined with the WITHOUT ROWID then you could change , id_of_the_row = 0;. The value will then be meaningless.

Testing/Results the version of the above that was used to test the above is :-

-- Solely for testing the code below
DROP TABLE IF EXISTS MGOFile;
CREATE TABLE IF NOT EXISTS MGOFile (File TEXT PRIMARY KEY);

-- Some testing data
INSERT INTO MGOFile VALUES
    ('M:\_TV/9-1-1.so2e09.web.x264-tbs[eztv].mkv'),
    ('M:\_TV/9-1-1.so2e09.web.x265-tbs[eztv].mkv'),
    ('M:\_TV/9-1-1.so2e09.web.x266-tbs[eztv].mkv'),
    ('M:\_TV/9-1-1.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv'),
    ('M:\_TV/9-1-1.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x277-tbs[eztv].mkv'),
    ('M:\_TV/9-1-1.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x278-tbs[eztv].mkv'),
    ('M:\_TV/9-1-1.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x279-tbs[eztv].mkv'),
    ('M:\_TV/9-1-1.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x280-tbs[eztv].mkv')
;

SELECT substr(File,170,8) FROM MGOFile GROUP BY Substr(File,8,170) HAVING count() > 1;

-- The code
DROP TABLE IF EXISTS lastupdated;
-- Create the logging table
CREATE TABLE IF NOT EXISTS lastupdated (counter, lastfile_before, lastfile_after, id_of_the_row);
-- Initialise it so it's plain to see if nothing has been done
INSERT INTO lastupdated VALUES(0,'nothing','nothing',0);
-- Add the Trigger to record the debugging information BEFORE the update
CREATE TRIGGER IF NOT EXISTS monitorupdateprogress
    BEFORE UPDATE ON MGOFile
    BEGIN
        UPDATE lastupdated SET counter = counter +1, lastfile_before = old.File, lastfile_after = new.File, id_of_the_row = old.rowid;
    END
;
SELECT * FROM MGOFile;
UPDATE OR FAIL MGOFile -- OR FAIL will halt but NOT ROLLBACK
    SET File = 'T:\' || substr(File, 8, 170) -- <<<<<<<<<<<<<<<<<<<< truncate reduced to force UNIQUE constraint
    WHERE File like 'M:\_TV%';
SELECT * FROM lastupdated; -- will not run if there is a fail

When the above is run then the message is :-

UPDATE OR FAIL MGOFile -- OR FAIL will halt but NOT ROLLBACK
    SET File = 'T:\' || substr(File, 8, 170) -- <<<<<<<<<<<<<<<<<<<< truncate reduced to force UNIQUE constraint
    WHERE File like 'M:\_TV%'
> UNIQUE constraint failed: MGOFile.File
> Time: 0.094s

Running SELECT * FROM lastupdated; returns :-

counter

6

lastfile_before   =

M:_TV/9-1-1.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x278-tbs[eztv].mkv

lastfile_after

T:\9-1-1.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x27

id_of_the_row

6

In the above contrived example the issue can easily be determined (albeit that the duplicate search also found the same issue) as the error is on the 6th row and at the row that contains mkv.so2e09.web.x278-tbs[eztv] but was truncated by the update to .mkv.so2e09.web.x27 hence it is a duplicate of the 5th row which has .mkv.so2e09.web.x277-tbs[eztv] but was also truncated to .mkv.so2e09.web.x27.

P.S. Have you tried using just

UPDATE MGOFile
SET File = 'T:\' || substr(File, 8)
WHERE File like 'M:\_TV%';

i.e. removing the truncation.


问:
Git: show dates in UTC
The following command shows some metadata about the last git commit in json format:

```<code>git show --quiet HEAD --pretty=format:"{\"hash\":\"%h\", \"author\":\"%cn\", \"commit date\":\"%cd\"}"

{
  "hash":"0fc0fc0",
  "author":"Adam Matan",
  "commit date":"Sun Jan 26 12:26:19 2014 +0200"}
}
</code>```

Is there a way to present the date in the UTC/GMT time zone, e.g. "Sun Jan 26 10:26:19 2014" ?

答: Technically git's Unix timestamp format (e.g. via --date='unix' / --format='%at') is always in UTC too. See https://git-scm.com/docs/git-log / https://git-scm.com/docs/pretty-formats for details.

Title: Git: show dates in UTC

Body:
The following command shows some metadata about the last git commit in json format:

git show --quiet HEAD --pretty=format:"{\"hash\":\"%h\", \"author\":\"%cn\", \"commit date\":\"%cd\"}"

{
  "hash":"0fc0fc0",
  "author":"Adam Matan",
  "commit date":"Sun Jan 26 12:26:19 2014 +0200"}
}

Is there a way to present the date in the UTC/GMT time zone, e.g. "Sun Jan 26 10:26:19 2014" ?


问:
Counting particular words
I'm working on a function that can count the number of words (including contractions like couldn't) in a list having exactly five letters.

I searched the internet for a similar issue but came up empty-handed.

```<code>def word_count(wlist):
    """ This function counts the number of words (including contractions like couldn't) in a list w/ exactly 5
        letters."""
    w = 0
    for word in x:
        w += 1 if len(word) == 5 else 0
    return w

x = ["adsfe", "as", "jkiejjl", "jsengd'e", "jjies"]
print(word_count(x))
</code>```

I'd like this function to count the number of words (including contractions like couldn't) in a list w/ exactly five letters. Any feedback is appreciated.

答:
Another way with filter:</p>

```<code>wordlist = ["adsfe", "as", "jkiejjl", "jseke", "jjies"]
len(list(filter(lambda x: len(x)==5, wordlist)))
</code>```

Title: Counting particular words

Body:
I'm working on a function that can count the number of words (including contractions like couldn't) in a list having exactly five letters.

I searched the internet for a similar issue but came up empty-handed.

def word_count(wlist):
    """ This function counts the number of words (including contractions like couldn't) in a list w/ exactly 5
        letters."""
    w = 0
    for word in x:
        w += 1 if len(word) == 5 else 0
    return w

x = ["adsfe", "as", "jkiejjl", "jsengd'e", "jjies"]
print(word_count(x))

I'd like this function to count the number of words (including contractions like couldn't) in a list w/ exactly five letters. Any feedback is appreciated.

Body:
Another way with filter:

wordlist = ["adsfe", "as", "jkiejjl", "jseke", "jjies"]
len(list(filter(lambda x: len(x)==5, wordlist)))


问:
Type Observable<{} | AppUser> is not assignable to <AppUser> RxJS Of operator
Using Angular 6.1 and RxJs 6, I'm trying to implement a resolver for a component on an individual user.

My userService http call is this:

```<code>getUserById(id: string): Observable<AppUser> {
    return this.http.get<AppUser>(this.baseURL + id, httpOptions);
}
</code>```

And my resolver:

```<code>import { Injectable } from "@angular/core";
import { Resolve, Router, ActivatedRouteSnapshot } from "@angular/router";
import { AppUser } from "../models/User/IAppUser";
import { UserService } from "../services/users/user.service";
import { AlertifyService } from "../../coreModule/alertify/alertify.service";
import { Observable, of } from "rxjs";
import { catchError } from "rxjs/operators";

@Injectable()
export class UserDetailResolver implements Resolve<AppUser> {
  constructor(
    private userService: UserService,
    private router: Router,
    private alertify: AlertifyService
  ) { }

  resolve(route: ActivatedRouteSnapshot): Observable<AppUser> {
    return this.userService.getUserById(route.params['id'])
      .pipe(
        catchError(error => {
          this.alertify.error('Problem retrieving data');
          this.router.navigate(['/home']);
          return of(null)
        })
      );
  }
</code>```

But because I'm trying to return null instead of an AppUser typescript is throwing an error. Not sure what I'm doing wrong since I thought rxjs of was supposed to handle this.

答:
Try

```<code>of(null as AppUser)
</code>```

or

```<code>of(undefined as AppUser)
</code>```

Body:
Using Angular 6.1 and RxJs 6, I'm trying to implement a resolver for a component on an individual user.

My userService http call is this:

getUserById(id: string): Observable<AppUser> {
    return this.http.get<AppUser>(this.baseURL + id, httpOptions);
}

And my resolver:

import { Injectable } from "@angular/core";
import { Resolve, Router, ActivatedRouteSnapshot } from "@angular/router";
import { AppUser } from "../models/User/IAppUser";
import { UserService } from "../services/users/user.service";
import { AlertifyService } from "../../coreModule/alertify/alertify.service";
import { Observable, of } from "rxjs";
import { catchError } from "rxjs/operators";

@Injectable()
export class UserDetailResolver implements Resolve<AppUser> {
  constructor(
    private userService: UserService,
    private router: Router,
    private alertify: AlertifyService
  ) { }

  resolve(route: ActivatedRouteSnapshot): Observable<AppUser> {
    return this.userService.getUserById(route.params['id'])
      .pipe(
        catchError(error => {
          this.alertify.error('Problem retrieving data');
          this.router.navigate(['/home']);
          return of(null)
        })
      );
  }

But because I'm trying to return null instead of an AppUser typescript is throwing an error. Not sure what I'm doing wrong since I thought rxjs of was supposed to handle this.

Body:
Try

of(null as AppUser)

or

of(undefined as AppUser)


问:
can php limit actions based on ip address
i have 2 links that display notifications on my website and its being abused. is there a way to limit the amount of times a user can click the links based on ip address i dont want to block anyone i just want to reduce the amount of times a person can click this link. essentially limiting the requests that can be made </p>

答:
Yes, implement a simple IP filter using $_SERVER["HTTP_CLIENT_IP"])

confer http://www.php.net/manual/en/language.variables.predefined.php


问:
Make the text to be in the middle of the image when mouse hovers over the image
I wanted to add a heading(bold) and a subheading(not bold) on all the images on a webpage when mouse hovers over it. I already have the effect where the image fades/changes color upon hovering. Following is the image: https://imgur.com/a/xLXSUkx

Here's the HTML code for it:

```<code><div class="JA-linkWrap JA-Notprojects JA-NotObjects floatleft" style="width:300px;">

        <a href="https://canadacouncil.ca/initiatives/venice-biennale"
        class="JA-projectPageLink">

          <img src="images/GRID/111%20jpeg%20grid.jpg" alt="" class="JA-
newsmediaImage">
         <h2 class = "img_head"> The Octa. </h2>
         <p class = "img_description"> Arch. </p>

            </a>

    </div>
</code>```

This is the CSS for .JA-linkWrap:

```<code>.JA-linkWrap {
   float: left;
   margin: 12px;
}
</code>```

More CSS:

```<code>* {
    margin: 0;
    padding: 0;
    border: 0;
}

.JA-linkWrap img:hover {
    -webkit-filter: brightness(90%);
}

.img_head{
  position: absolute;
  color: #000;
  visibility: hidden;
  opacity: 0;
  transition: opacity.2s, visibility .2s;

}

.img_description{
  position:inherit;

  color:#000;
  visibility: hidden;
  opacity: 0;
  transition: opacity.2s, visibility .2s;
}

.JA-linkWrap:hover .img_description{
  visibility: visible;
  opacity: 1;
}

.JA-linkWrap:hover .img_head{
   visibility: visible;
  opacity: 1;
}
</code>```

Here's the outcome of my attempt when I hover the mouse over the image: https://imgur.com/a/Fkuf0eE As you can see the heading and description of the image are both under the image. I want them to be in the center of the image. Please be specific, I am new to this.

答:
You should add a wrapper to the title elements, and then set the size of the wrapper like the box of the image. Then use flexbox to vertically align titles inside the wrapper. Also, remove inline styles for width: 300px

.JA-linkWrap {
   float: left;
   margin: 12px;
  position: relative;
}

* {
    margin: 0;
    padding: 0;
    border: 0;
}

.JA-linkWrap:hover img {
    -webkit-filter: brightness(90%);
}

.img_head{
  color: #000;
  visibility: hidden;
  opacity: 0;
  transition: opacity.2s, visibility .2s;
}

.img_description{
  color:#000;
  visibility: hidden;
  opacity: 0;
  transition: opacity.2s, visibility .2s;
}

.JA-linkWrap:hover .img_description, .JA-linkWrap:hover .img_head {
  visibility: visible;
  opacity: 1;
}

.title-wrapper {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  flex-direction: column;
  justify-content: center;
  flex-wrap: wrap;
}

.title-wrapper .img_head, .title-wrapper .img_description {
    background-color: white;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div class="JA-linkWrap JA-Notprojects JA-NotObjects floatleft">

          <img src="https://picsum.photos/id/237/500/300" alt="" class="JA-
newsmediaImage">

          <div class="title-wrapper">
         <h2 class = "img_head"> The Octa. </h2>
         <p class = "img_description"> Arch. </p>
          </div>

    </div>   </code>```

Body:
I wanted to add a heading(bold) and a subheading(not bold) on all the images on a webpage when mouse hovers over it. I already have the effect where the image fades/changes color upon hovering. Following is the image: https://imgur.com/a/xLXSUkx

Here's the HTML code for it:

 The Octa.

 Arch.

This is the CSS for .JA-linkWrap:

.JA-linkWrap {
   float: left;
   margin: 12px;
}

More CSS:

* {
    margin: 0;
    padding: 0;
    border: 0;
}

.JA-linkWrap img:hover {
    -webkit-filter: brightness(90%);
}

.img_head{
  position: absolute;
  color: #000;
  visibility: hidden;
  opacity: 0;
  transition: opacity.2s, visibility .2s;

}

.img_description{
  position:inherit;

  color:#000;
  visibility: hidden;
  opacity: 0;
  transition: opacity.2s, visibility .2s;
}

.JA-linkWrap:hover .img_description{
  visibility: visible;
  opacity: 1;
}

.JA-linkWrap:hover .img_head{
   visibility: visible;
  opacity: 1;
}

Here's the outcome of my attempt when I hover the mouse over the image: https://imgur.com/a/Fkuf0eE As you can see the heading and description of the image are both under the image. I want them to be in the center of the image. Please be specific, I am new to this.

Body:
You should add a wrapper to the title elements, and then set the size of the wrapper like the box of the image. Then use flexbox to vertically align titles inside the wrapper. Also, remove inline styles for width: 300px

.JA-linkWrap {
   float: left;
   margin: 12px;
  position: relative;
}

* {
    margin: 0;
    padding: 0;
    border: 0;
}

.JA-linkWrap:hover img {
    -webkit-filter: brightness(90%);
}

.img_head{
  color: #000;
  visibility: hidden;
  opacity: 0;
  transition: opacity.2s, visibility .2s;
}

.img_description{
  color:#000;
  visibility: hidden;
  opacity: 0;
  transition: opacity.2s, visibility .2s;
}

.JA-linkWrap:hover .img_description, .JA-linkWrap:hover .img_head {
  visibility: visible;
  opacity: 1;
}

.title-wrapper {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  flex-direction: column;
  justify-content: center;
  flex-wrap: wrap;
}

.title-wrapper .img_head, .title-wrapper .img_description {
    background-color: white;
}

<div class="JA-linkWrap JA-Notprojects JA-NotObjects floatleft">

        <a href="https://canadacouncil.ca/initiatives/venice-biennale"
        class="JA-projectPageLink">

          <img src="https://picsum.photos/id/237/500/300" alt="" class="JA-
newsmediaImage">

          <div class="title-wrapper">
         <h2 class = "img_head"> The Octa. </h2>
         <p class = "img_description"> Arch. </p>
          </div>

            </a>

    </div>


问:
Stopping the infinite dialog loop
In short I want to know how to stop the multi-prompt example on the Microsoft sample git repo looping forever.

I've been looking over the V4 documentation and I am unable to find anything that's hinted at the solution here.

Microsoft have published a sample for making use of the multi-prompt dialog available here:
https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/05.multi-turn-prompt

If you clone and run the activity runs as follows;

you: send a message

bot: responds with opening dialog

you: respond to dialog

bot: advances to next step of dialog

....

continues to final step when it runs

return await stepContext.EndDialogAsync(cancellationToken: cancellationToken);
```

<p>The bot sends the final message in the waterfall steps and waits for another message from the user. Once again when the user sends any message the bot activates the dialog waterfall again.</p>

<p>Obviously because of this method in <code>DialogBot.cs</code>, every time the user sends a message the bot goes into the dialog.</p>

<pre class="lang-cs prettyprint-override"><code>protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
        {
            Logger.LogInformation("Running dialog with Message Activity.");

            // Run the Dialog with the new message Activity.
            await Dialog.Run(turnContext, ConversationState.CreateProperty<DialogState>(nameof(DialogState)), cancellationToken);
        }
</code>```

I want to stop that happening and only run the dialog once, the dialog should not activate again once the dialog ends the first time.

答:
Take a close look at sample 45.state-management from the Botbuilder-Samples repo. It demonstrates how you can reference a set value in state to determine dialog flow. It would also be good for you to read over the "Save user and conversation data" doc, located here.

In short, you will need to do the following:

In the Startup.cs file, add the following. Be prepared to configure to meet your needs.

public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

            // Create the credential provider to be used with the Bot Framework Adapter.
            services.AddSingleton<ICredentialProvider, ConfigurationCredentialProvider>();

            // Create the Bot Framework Adapter with error handling enabled.
            services.AddSingleton<IBotFrameworkHttpAdapter, AdapterWithErrorHandler>();

            // Create the storage we'll be using for User and Conversation state. (Memory is great for testing purposes.)
            services.AddSingleton<IStorage, MemoryStorage>();

            // Create the User state.
            services.AddSingleton<UserState>();

            // Create the Conversation state.
            services.AddSingleton<ConversationState>();

            // Create the bot as a transient. In this case the ASP Controller is expecting an IBot.
            services.AddTransient<IBot, StateManagementBot>();
        }
    }
```

<p>In your <strong>"bot.cs"</strong> file, do the following. Again, this is an example, so tailor to your needs. First, set the state objects (_conversationState, _userState). Once that is done, you can set and recall state values according to the dialog flow using those value to help drive the next action. In this example, state is being referenced in order to determine if a user's name should be asked for again, or not.</p>

<pre class="lang-cs prettyprint-override"><code>namespace Microsoft.BotBuilderSamples
{
    public class StateManagementBot : ActivityHandler
    {
        private BotState _conversationState;
        private BotState _userState;

        public StateManagementBot(ConversationState conversationState, UserState userState)
        {
            _conversationState = conversationState;
            _userState = userState;
        }

        public override async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
        {
            await base.OnTurnAsync(turnContext, cancellationToken);

            // Save any state changes that might have occured during the turn.
            await _conversationState.SaveChangesAsync(turnContext, false, cancellationToken);
            await _userState.SaveChangesAsync(turnContext, false, cancellationToken);
        }

        protected override async Task OnMembersAddedAsync(IList<ChannelAccount> membersAdded, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
        {
            await turnContext.SendActivityAsync("Welcome to State Bot Sample. Type anything to get started.");
        }

        protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
        {
            // Get the state properties from the turn context.

            var conversationStateAccessors =  _conversationState.CreateProperty<ConversationData>(nameof(ConversationData));
            var conversationData = await conversationStateAccessors.GetAsync(turnContext, () => new ConversationData());

            var userStateAccessors = _userState.CreateProperty<UserProfile>(nameof(UserProfile));
            var userProfile = await userStateAccessors.GetAsync(turnContext, () => new UserProfile());

            if (string.IsNullOrEmpty(userProfile.Name))
            {
                // First time around this is set to false, so we will prompt user for name.
                if (conversationData.PromptedUserForName)
                {
                    // Set the name to what the user provided.
                    userProfile.Name = turnContext.Activity.Text?.Trim();

                    // Acknowledge that we got their name.
                    await turnContext.SendActivityAsync($"Thanks {userProfile.Name}. To see conversation data, type anything.");

                    // Reset the flag to allow the bot to go though the cycle again.
                    conversationData.PromptedUserForName = false;
                }
                else
                {
                    // Prompt the user for their name.
                    await turnContext.SendActivityAsync($"What is your name?");

                    // Set the flag to true, so we don't prompt in the next turn.
                    conversationData.PromptedUserForName = true;
                }
            }
            else
            {
                // Add message details to the conversation data.
                // Convert saved Timestamp to local DateTimeOffset, then to string for display.
                var messageTimeOffset = (DateTimeOffset) turnContext.Activity.Timestamp;
                var localMessageTime = messageTimeOffset.ToLocalTime();
                conversationData.Timestamp = localMessageTime.ToString();
                conversationData.ChannelId = turnContext.Activity.ChannelId.ToString();

                // Display state data.
                await turnContext.SendActivityAsync($"{userProfile.Name} sent: {turnContext.Activity.Text}");
                await turnContext.SendActivityAsync($"Message received at: {conversationData.Timestamp}");
                await turnContext.SendActivityAsync($"Message received from: {conversationData.ChannelId}");
            }
        }
    }
}
</code>```

In this way, you can track whether a user has already visited a particular dialog. If the value is true, then the dialog is skipped and the user is redirected. Hope of help!

Title: Stopping the infinite dialog loop

Body:
In short I want to know how to stop the multi-prompt example on the Microsoft sample git repo looping forever.

I've been looking over the V4 documentation and I am unable to find anything that's hinted at the solution here.

Microsoft have published a sample for making use of the multi-prompt dialog available here:
https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/05.multi-turn-prompt

If you clone and run the activity runs as follows;

you: send a message

bot: responds with opening dialog

you: respond to dialog

bot: advances to next step of dialog

....

continues to final step when it runs

return await stepContext.EndDialogAsync(cancellationToken: cancellationToken);

The bot sends the final message in the waterfall steps and waits for another message from the user. Once again when the user sends any message the bot activates the dialog waterfall again.

Obviously because of this method in DialogBot.cs, every time the user sends a message the bot goes into the dialog.

protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
        {
            Logger.LogInformation("Running dialog with Message Activity.");

            // Run the Dialog with the new message Activity.
            await Dialog.Run(turnContext, ConversationState.CreateProperty<DialogState>(nameof(DialogState)), cancellationToken);
        }

I want to stop that happening and only run the dialog once, the dialog should not activate again once the dialog ends the first time.

Body:
Take a close look at sample 45.state-management from the Botbuilder-Samples repo. It demonstrates how you can reference a set value in state to determine dialog flow. It would also be good for you to read over the "Save user and conversation data" doc, located here.

In short, you will need to do the following:

In the Startup.cs file, add the following. Be prepared to configure to meet your needs.

public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

            // Create the credential provider to be used with the Bot Framework Adapter.
            services.AddSingleton<ICredentialProvider, ConfigurationCredentialProvider>();

            // Create the Bot Framework Adapter with error handling enabled.
            services.AddSingleton<IBotFrameworkHttpAdapter, AdapterWithErrorHandler>();

            // Create the storage we'll be using for User and Conversation state. (Memory is great for testing purposes.)
            services.AddSingleton<IStorage, MemoryStorage>();

            // Create the User state.
            services.AddSingleton<UserState>();

            // Create the Conversation state.
            services.AddSingleton<ConversationState>();

            // Create the bot as a transient. In this case the ASP Controller is expecting an IBot.
            services.AddTransient<IBot, StateManagementBot>();
        }
    }

In your "bot.cs" file, do the following. Again, this is an example, so tailor to your needs. First, set the state objects (_conversationState, _userState). Once that is done, you can set and recall state values according to the dialog flow using those value to help drive the next action. In this example, state is being referenced in order to determine if a user's name should be asked for again, or not.

namespace Microsoft.BotBuilderSamples
{
    public class StateManagementBot : ActivityHandler
    {
        private BotState _conversationState;
        private BotState _userState;

        public StateManagementBot(ConversationState conversationState, UserState userState)
        {
            _conversationState = conversationState;
            _userState = userState;
        }

        public override async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
        {
            await base.OnTurnAsync(turnContext, cancellationToken);

            // Save any state changes that might have occured during the turn.
            await _conversationState.SaveChangesAsync(turnContext, false, cancellationToken);
            await _userState.SaveChangesAsync(turnContext, false, cancellationToken);
        }

        protected override async Task OnMembersAddedAsync(IList<ChannelAccount> membersAdded, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
        {
            await turnContext.SendActivityAsync("Welcome to State Bot Sample. Type anything to get started.");
        }

        protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
        {
            // Get the state properties from the turn context.

            var conversationStateAccessors =  _conversationState.CreateProperty<ConversationData>(nameof(ConversationData));
            var conversationData = await conversationStateAccessors.GetAsync(turnContext, () => new ConversationData());

            var userStateAccessors = _userState.CreateProperty<UserProfile>(nameof(UserProfile));
            var userProfile = await userStateAccessors.GetAsync(turnContext, () => new UserProfile());

            if (string.IsNullOrEmpty(userProfile.Name))
            {
                // First time around this is set to false, so we will prompt user for name.
                if (conversationData.PromptedUserForName)
                {
                    // Set the name to what the user provided.
                    userProfile.Name = turnContext.Activity.Text?.Trim();

                    // Acknowledge that we got their name.
                    await turnContext.SendActivityAsync($"Thanks {userProfile.Name}. To see conversation data, type anything.");

                    // Reset the flag to allow the bot to go though the cycle again.
                    conversationData.PromptedUserForName = false;
                }
                else
                {
                    // Prompt the user for their name.
                    await turnContext.SendActivityAsync($"What is your name?");

                    // Set the flag to true, so we don't prompt in the next turn.
                    conversationData.PromptedUserForName = true;
                }
            }
            else
            {
                // Add message details to the conversation data.
                // Convert saved Timestamp to local DateTimeOffset, then to string for display.
                var messageTimeOffset = (DateTimeOffset) turnContext.Activity.Timestamp;
                var localMessageTime = messageTimeOffset.ToLocalTime();
                conversationData.Timestamp = localMessageTime.ToString();
                conversationData.ChannelId = turnContext.Activity.ChannelId.ToString();

                // Display state data.
                await turnContext.SendActivityAsync($"{userProfile.Name} sent: {turnContext.Activity.Text}");
                await turnContext.SendActivityAsync($"Message received at: {conversationData.Timestamp}");
                await turnContext.SendActivityAsync($"Message received from: {conversationData.ChannelId}");
            }
        }
    }
}

In this way, you can track whether a user has already visited a particular dialog. If the value is true, then the dialog is skipped and the user is redirected. Hope of help!