问:
In ASP.net, what kind of IF statement could I use to hide a div if the image inside it matches the current page URL?
This is within Sitefinity if that matters, and I am really new at ASP.NET and C#.

I have an image-based navigation element at the bottom of a page that links to different articles using the same template.   There are 5 articles, and I would like the link to the active page/article to be hidden so there is a grid of 4 image links.

Here's a screenshot:

https://i.imgur.com/PG2Sfpo.png

Here is the code behind it:

```<code>@{
    string navTitle = string.Empty;
    string url = string.Empty;

    if (Model.CurrentSiteMapNode != null && Model.CurrentSiteMapNode.ParentNode != null)
    {
        if (Model.CurrentSiteMapNode.Title == "Home")
        {
            navTitle = Model.CurrentSiteMapNode.ParentNode.Title;
        }
        else
        {
            navTitle = Model.CurrentSiteMapNode.Title;
        }
        url = Model.CurrentSiteMapNode.ParentNode.Url;
    }
}
 <div class="foundation-stories-container">
    @foreach (var node in Model.Nodes)
    {
        @RenderRootLevelNode(node);
    }
</div>

@*Here is specified the rendering for the root level*@
@helper RenderRootLevelNode(NodeViewModel node)
{
string[] thisPage = (node.Url).Split('/');
string thisImage = thisPage[4] + ".jpg";
 <a href="@node.Url" target="@node.LinkTarget">
     <div class="foundation-story-block">
         <div class="hovereffect">
             <img src="[OUR WEBSITE URL]/stories/@thisImage" class="img-fluid">
             <div class="overlay">
                 <h2>@node.Title</h2>
             </div>
         </div>
     </div>
 </a>
}
</code>```

So we're already getting the page URL and image file name

```<code>string[] thisPage = (node.Url).Split('/');
string thisImage = thisPage[4] + ".jpg";
</code>```

Is this as easy as doing the following?

```<code>if (thisImage = thisPage)
{
   foundation-story-block.AddClassToHtmlControl("hide")
}

</code>```

Seems easy enough, but I don't know where to start.

I'm better at Javascript, so I do have a JS solution in place for this already, but I'd really like to find a cleaner way to do it.

```<code><script type="text/javascript">

$(document).ready(function() {

    var active = window.location.pathname.split("/").pop()

    var name = active;
    name = name.replace(/-/g, ' ');

    jQuery.expr[":"].Contains = jQuery.expr.createPseudo(function(arg) {
    return function( elem ) {
        return jQuery(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >=
    0;
    };
});

$("h2:Contains('" + name + "')").closest(".foundation-story-block").addClass("hide");

});

</script>
</code>```

This exists on the main template page.

Gets the last part of the URL

Sets that as a variable called "name"

Changes the dash to a space if there is one (most of the pages are associated with names so it's like /first-last)

Then it goes and looks at the  which is where the title of the page lives, and if it equals the "name" variable, the ".hide" class is added to the block.

Thanks for any help anyone can provide.

答:
You could bind a click event to your elements with the foundation-story-block class. The reason I use .on instead of .click is because when using UpdatePanels the click event won't fire after an UpdatePanel has it's update event triggered - you might encounter a similar problem with your dynamic binding so I used .on to avoid this.

```<code>$(".foundation-story-block").on("click", function() {
    // Remove the "hide" class from any elements that have it applied
    $.each($(".foundation-story-block.hide"), function(index, value) {
        // Remove the class using the "this" context from the anonymous function
        $(this).removeClass("hide");
    });

    // Add the "hide" class to the element that was clicked
    $(this).addClass("hide");
});
</code>```

I haven't run this though an IDE so it might not be 100% correct but it will put you on the correct path.

Body:
This is within Sitefinity if that matters, and I am really new at ASP.NET and C#.

I have an image-based navigation element at the bottom of a page that links to different articles using the same template.   There are 5 articles, and I would like the link to the active page/article to be hidden so there is a grid of 4 image links.

Here's a screenshot:

https://i.imgur.com/PG2Sfpo.png

Here is the code behind it:

@{
    string navTitle = string.Empty;
    string url = string.Empty;

    if (Model.CurrentSiteMapNode != null && Model.CurrentSiteMapNode.ParentNode != null)
    {
        if (Model.CurrentSiteMapNode.Title == "Home")
        {
            navTitle = Model.CurrentSiteMapNode.ParentNode.Title;
        }
        else
        {
            navTitle = Model.CurrentSiteMapNode.Title;
        }
        url = Model.CurrentSiteMapNode.ParentNode.Url;
    }
}

    @foreach (var node in Model.Nodes)
    {
        @RenderRootLevelNode(node);
    }

@*Here is specified the rendering for the root level*@
@helper RenderRootLevelNode(NodeViewModel node)
{
string[] thisPage = (node.Url).Split('/');
string thisImage = thisPage[4] + ".jpg";

@node.Title

}

So we're already getting the page URL and image file name

string[] thisPage = (node.Url).Split('/');
string thisImage = thisPage[4] + ".jpg";

Is this as easy as doing the following?

if (thisImage = thisPage)
{
   foundation-story-block.AddClassToHtmlControl("hide")
}

Seems easy enough, but I don't know where to start.

I'm better at Javascript, so I do have a JS solution in place for this already, but I'd really like to find a cleaner way to do it.

This exists on the main template page.

Gets the last part of the URL

Sets that as a variable called "name"

Changes the dash to a space if there is one (most of the pages are associated with names so it's like /first-last)

Then it goes and looks at the  which is where the title of the page lives, and if it equals the "name" variable, the ".hide" class is added to the block.

Thanks for any help anyone can provide.

Body:
You could bind a click event to your elements with the foundation-story-block class. The reason I use .on instead of .click is because when using UpdatePanels the click event won't fire after an UpdatePanel has it's update event triggered - you might encounter a similar problem with your dynamic binding so I used .on to avoid this.

$(".foundation-story-block").on("click", function() {
    // Remove the "hide" class from any elements that have it applied
    $.each($(".foundation-story-block.hide"), function(index, value) {
        // Remove the class using the "this" context from the anonymous function
        $(this).removeClass("hide");
    });

    // Add the "hide" class to the element that was clicked
    $(this).addClass("hide");
});

I haven't run this though an IDE so it might not be 100% correct but it will put you on the correct path.


来源: stackexchange

问:
USSD call without user confirmation
I'm using the following code for calling from the app:

let number : String = "*10*60#"
 if  let url : URL = URL(string: "tel://\(number)"){
   UIApplication.shared.open(url)}

But it asks for the permission of the user
and that's ok but I don't want to let the user know the USSD code that I want to call.
I'm using this for calling to USSD codes for buying packages of mobile internet. Is there a way of changing that? I mean change the text so that instead of the number that this is going to call, it would say, "do you want to purchase this package?"

答:
If the user cannot see what number you are calling before granting permission, what stops you from calling a premium-rate number (like a 900 or 976 number in the USA) that charges $1000 to the user's cellular phone bill for the call?

Answer: nothing. That's why Apple does not let you call a number without user approval.

Also, even if you show the number, this sounds suspiciously like something Apple would reject on the grounds of not using Apple's own In-App Purchase system.

OwnerDisplayName: Reddy Tintaya

ContentLicense: CC BY-SA 4.0

Title: USSD call without user confirmation


问:
Not able to install dplyr in R 3.2.1
I am not able to install dplyr. I have the following answer after trying the installation

```<code>  There are binary versions available but the source versions are later:
          binary source needs_compilation
backports  1.0.3  1.1.4             FALSE
Rcpp      0.12.6  1.0.1              TRUE
tibble       1.1  2.1.1              TRUE
dplyr      0.5.0  0.8.1              TRUE

  Binaries will be installed
Packages which are only available in source form, and may need compilation of
  C/C++/Fortran: ‘utf8’ ‘vctrs’ ‘fansi’ ‘glue’ ‘rlang’ ‘tidyselect’
  These will not be installed
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 2651k  100 2651k    0     0   464k      0  0:00:05  0:00:05 --:--:--  529k
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  165k  100  165k    0     0   188k      0 --:--:-- --:--:-- --:--:--  233k
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 3722k  100 3722k    0     0   613k      0  0:00:06  0:00:06 --:--:--  732k

The downloaded binary packages are in
    /var/folders/np/f2p1wtb97f9_b_y_x0m1s60w0000gn/T//Rtmpm572i3/downloaded_packages
installing the source packages ‘backports’, ‘pillar’

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 13859  100 13859    0     0  37534      0 --:--:-- --:--:-- --:--:-- 70350
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  223k  100  223k    0     0   202k      0  0:00:01  0:00:01 --:--:--  242k
* installing *source* package ‘backports’ ...
** package ‘backports’ successfully unpacked and MD5 sums checked
** libs
sh: make: command not found
ERROR: compilation failed for package ‘backports’
* removing ‘/Library/Frameworks/R.framework/Versions/3.2/Resources/library/backports’
Warning in install.packages :
  installation of package ‘backports’ had non-zero exit status
ERROR: dependencies ‘fansi’, ‘rlang’, ‘utf8’, ‘vctrs’ are not available for package ‘pillar’
* removing ‘/Library/Frameworks/R.framework/Versions/3.2/Resources/library/pillar’
Warning in install.packages :
  installation of package ‘pillar’ had non-zero exit status

The downloaded source packages are in
    ‘/private/var/folders/np/f2p1wtb97f9_b_y_x0m1s60w0000gn/T/Rtmpm572i3/downloaded_packages’
</code>```

My session info:

```<code>R version 3.2.1 (2015-06-18)
Platform: x86_64-apple-darwin10.8.0 (64-bit)
Running under: OS X 10.8.5 (Mountain Lion)

locale:
[1] es_ES.UTF-8/es_ES.UTF-8/es_ES.UTF-8/C/es_ES.UTF-8/es_ES.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base

other attached packages:
[1] remotes_2.0.4

loaded via a namespace (and not attached):
[1] httr_1.4.0     R6_2.4.0       tools_3.2.1    RCurl_1.95-4.8 digest_0.6.10  bitops_1.0-6
</code>```

答:
Snark aside, this is going to be hard. As suggested by comments, if it's at all possible your easiest route will be to update your version of R to something current or nearly current.

It's theoretically possible to compile/install R and packages for older versions of R/on very old OS's, but in practice it gets hard pretty quickly.  Your best bet is to see if you can install development tools from here (this may be a little hard as the information isn't always applicable/kept current for old OS versions).

R version is probably a bigger barrier than the OS; CRAN provides binaries for OS >= 10.6. However:

binaries are not provided for older versions of R

new packages may explicitly depend on newer versions of R.

Without access to development tools you could try to use the snapshot package to use the MRAN "time machine" (mirrors of previous instances of CRAN) - it goes back to September 2014. However, this will not pick up binaries for any packages that were first released after your version of R was current, which includes most of the tidyverse packages you're trying to install ...

Title: Not able to install dplyr in R 3.2.1

Body:
I am not able to install dplyr. I have the following answer after trying the installation

  There are binary versions available but the source versions are later:
          binary source needs_compilation
backports  1.0.3  1.1.4             FALSE
Rcpp      0.12.6  1.0.1              TRUE
tibble       1.1  2.1.1              TRUE
dplyr      0.5.0  0.8.1              TRUE

  Binaries will be installed
Packages which are only available in source form, and may need compilation of
  C/C++/Fortran: ‘utf8’ ‘vctrs’ ‘fansi’ ‘glue’ ‘rlang’ ‘tidyselect’
  These will not be installed
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 2651k  100 2651k    0     0   464k      0  0:00:05  0:00:05 --:--:--  529k
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  165k  100  165k    0     0   188k      0 --:--:-- --:--:-- --:--:--  233k
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 3722k  100 3722k    0     0   613k      0  0:00:06  0:00:06 --:--:--  732k

The downloaded binary packages are in
    /var/folders/np/f2p1wtb97f9_b_y_x0m1s60w0000gn/T//Rtmpm572i3/downloaded_packages
installing the source packages ‘backports’, ‘pillar’

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 13859  100 13859    0     0  37534      0 --:--:-- --:--:-- --:--:-- 70350
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  223k  100  223k    0     0   202k      0  0:00:01  0:00:01 --:--:--  242k
* installing *source* package ‘backports’ ...
** package ‘backports’ successfully unpacked and MD5 sums checked
** libs
sh: make: command not found
ERROR: compilation failed for package ‘backports’
* removing ‘/Library/Frameworks/R.framework/Versions/3.2/Resources/library/backports’
Warning in install.packages :
  installation of package ‘backports’ had non-zero exit status
ERROR: dependencies ‘fansi’, ‘rlang’, ‘utf8’, ‘vctrs’ are not available for package ‘pillar’
* removing ‘/Library/Frameworks/R.framework/Versions/3.2/Resources/library/pillar’
Warning in install.packages :
  installation of package ‘pillar’ had non-zero exit status

The downloaded source packages are in
    ‘/private/var/folders/np/f2p1wtb97f9_b_y_x0m1s60w0000gn/T/Rtmpm572i3/downloaded_packages’

My session info:

R version 3.2.1 (2015-06-18)
Platform: x86_64-apple-darwin10.8.0 (64-bit)
Running under: OS X 10.8.5 (Mountain Lion)

locale:
[1] es_ES.UTF-8/es_ES.UTF-8/es_ES.UTF-8/C/es_ES.UTF-8/es_ES.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base

other attached packages:
[1] remotes_2.0.4

loaded via a namespace (and not attached):
[1] httr_1.4.0     R6_2.4.0       tools_3.2.1    RCurl_1.95-4.8 digest_0.6.10  bitops_1.0-6


问:
How can I expose/launch Anaconda on Windows?
I just downloaded and installed Anaconda, for Windows, from here.

https://docs.anaconda.com/anaconda/install/windows/

I just followed the prompts and everything seemed to have installed normally, and I see the directory and all folders and files here.

C:\Users\my_path\AppData\Local\Continuum\anaconda3

However, when I click the Start button I don't see Anaconda installed as a shortcut and when I search for it (next to the Start button) I don't see anything related to Anaconda.  Is there an easy way to create shortcuts for Anaconda, Spyder, the command prompt, etc?  Thanks.

答: First, go that .exe location of Anaconda navigator. Then right click --> send to desktop. Now you have a shortcut on the desktop. Now on the desktop, right click on the shortcut and you will see 'pin to start'. </p>


问:
How to delete line from CSV as they are read in Bash
I am currently doing this:

```<code>while read l
do
  echo git add $l/
  git add $l/
  # sed -i -e '1,1d' data/commit-folders.csv
  # echo git commit -am "'Autocommit'"
  # git commit -uno -am "'Autocommit'"
  # echo git push origin master
  # git push origin master
done < data/commit-folders.csv
</code>```

Essentially just git add <folder> for a list of folders in a CSV file. I would like for this to be more robust, in that every time it restarts it restarts from where it left off. So I added that commented out line which does an in-place delete sed -i -e '1,1d' data/commit-folders.csv. However, with while read line, it messes up with the current line if they are being deleted. So I'm wondering how to do this properly.

How to iterate through a CSV file with <path> on each line, and delete the path once it is successfully git added. It seems like you need to have a loop that selects the first line from a file, and then deletes it from the file afterwards, rather than using while read line.

答:
you can use sed -i "/${l}/d" , it will find the exact line and delete it. This assumes that there would be no duplicate lines.

```<code>while read l
do
  echo git add $l/
  git add $l/
  # sed -i -e '1,1d' data/commit-folders.csv
  sed -i "/${l}/d" data/commit-folders.csv
  # echo git commit -am "'Autocommit'"
  # git commit -uno -am "'Autocommit'"
  # echo git push origin master
  # git push origin master
done < data/commit-folders.csv
</code>```

Body:
I am currently doing this:

while read l
do
  echo git add $l/
  git add $l/
  # sed -i -e '1,1d' data/commit-folders.csv
  # echo git commit -am "'Autocommit'"
  # git commit -uno -am "'Autocommit'"
  # echo git push origin master
  # git push origin master
done < data/commit-folders.csv

Essentially just git add <folder> for a list of folders in a CSV file. I would like for this to be more robust, in that every time it restarts it restarts from where it left off. So I added that commented out line which does an in-place delete sed -i -e '1,1d' data/commit-folders.csv. However, with while read line, it messes up with the current line if they are being deleted. So I'm wondering how to do this properly.

How to iterate through a CSV file with <path> on each line, and delete the path once it is successfully git added. It seems like you need to have a loop that selects the first line from a file, and then deletes it from the file afterwards, rather than using while read line.

Body:
you can use sed -i "/${l}/d" , it will find the exact line and delete it. This assumes that there would be no duplicate lines.

while read l
do
  echo git add $l/
  git add $l/
  # sed -i -e '1,1d' data/commit-folders.csv
  sed -i "/${l}/d" data/commit-folders.csv
  # echo git commit -am "'Autocommit'"
  # git commit -uno -am "'Autocommit'"
  # echo git push origin master
  # git push origin master
done < data/commit-folders.csv


问:
How to use FedEx Web Services in flutter
I'm developing an APP to track FedEx packages using flutter. Where should I integrate FedEx web service WSDL into my code so that I can send my tracking request to FedEx and get the response back?

Currently I'm testing with another api and able to get response by sending request directly to the url of this api. But FedEx web service does not work that way and I have to use their WSDL to set the url.

```<code>Beer.fromJSON(Map<String, dynamic> jsonMap) :
        id = jsonMap['id'],
        name = jsonMap['name'],
        tagline = jsonMap['tagline'],
        description = jsonMap['description'],
        image_url = jsonMap['image_url'];
}

Future<Stream<Beer>> getBeers() async {
  final String url = 'https://api.punkapi.com/v2/beers';

  final client = new http.Client();
  final streamedRest = await client.send(
      http.Request('get', Uri.parse(url))
  );

  return streamedRest.stream
      .transform(utf8.decoder)
      .transform(json.decoder)
      .expand((data) => (data as List))
      .map((data) => Beer.fromJSON(data));
}
</code>```

答:
WSDL isn't something you import into your app, or at least not with dart. It describes the requests that can be made to the various endpoints their server supports.

Fedex's documentation does a better job explaining than I could:

A SOAP request to, or response from a service is generated according to the service’s WSDL definition.

A WSDL is an XML document that provides information about what the service does, the methods that are available, their parameters, and parameter types. It describes how to communicate with the service in order to generate a request to, or decipher a response from, the service.

The purpose of a WSDL is to completely describe a web service to a client. A WSDL generally defines where the service is available and which communication protocol is used to talk to the service. It defines everything required to write a program that will work with an XML web service.

There's a good chance that the endpoint actually uses SOAP for the communication, which dart doesn't currently fully support. You're going to have to use something like dart:xml to generate requests that match the description in the WSDL, and then you can send them with the http.Client the same way as you have done for the other API.

Body:
I'm developing an APP to track FedEx packages using flutter. Where should I integrate FedEx web service WSDL into my code so that I can send my tracking request to FedEx and get the response back?

Currently I'm testing with another api and able to get response by sending request directly to the url of this api. But FedEx web service does not work that way and I have to use their WSDL to set the url.

Beer.fromJSON(Map<String, dynamic> jsonMap) :
        id = jsonMap['id'],
        name = jsonMap['name'],
        tagline = jsonMap['tagline'],
        description = jsonMap['description'],
        image_url = jsonMap['image_url'];
}

Future<Stream<Beer>> getBeers() async {
  final String url = 'https://api.punkapi.com/v2/beers';

  final client = new http.Client();
  final streamedRest = await client.send(
      http.Request('get', Uri.parse(url))
  );

  return streamedRest.stream
      .transform(utf8.decoder)
      .transform(json.decoder)
      .expand((data) => (data as List))
      .map((data) => Beer.fromJSON(data));
}


问:
Why comparing Strings in MySQL query is not working
I am running a very simple SELECT query in MySQL and it's not working.

```<code>SELECT string_name FROM table_name;
</code>```

This is giving me required output. Like

This is string one.

This is string two.

This is string three.

and so on...

But if I am running a query like this

```<code>SELECT * FROM table_name WHERE string_name='This is string one'
</code>```

It's not giving any output. I even tried TRIM function.

```<code>SELECT * FROM table_name WHERE TRIM(string_name)=TRIM('This is string one')
</code>```

But it's still not giving any output.

Please suggest what I am missing here. Is it because of some formatting or am I doing any silly mistake. By the way, Strings are saved as VARCHAR in the database.

答:
To reiterate from comments; sometimes "non-printing" control characters (like newlines) can make their way into data they were never intended to be a part of. You can test for this by checking CHAR_LENGTH of field values versus what you actually see. Obviously, on large amounts of data this can be difficult; but if you know of one problematic value already, you can use this method to confirm this is the problem on that row before attempting to identify the offending character.

Once this problem is confirmed, you can use queries with MySql's ASC() and substring functions to identify character codes until you find the character; it can be best to start from the end of the string and work back, as often the offending characters are at the end.

The character or characters identified in known problem rows are often the cause of other problem rows as well, so identifying the issue in one known row can actually help resolve all such problems.

Once the character code(s) are identified, queries like WHERE string_name LIKE CONCAT('%', CHAR(13), CHAR(10)) should work (in this case for traditional Windows newlines) to identify other similar problem rows. Obviously, adjust character codes and wildcards according to your circumstances.

If no row should ever have those characters anywhere, you should be able to clean up the data with an update like this:
UPDATE theTable SET theString = REPLACE(REPLACE(theString, CHAR(10), ''), CHAR(13), '') to remove the offending characters. Again, use the codes you've actually observed causing the problem; and you can convert them to spaces instead if circumstances are better handled that way, such as a newline between two words.

Body:
I am running a very simple SELECT query in MySQL and it's not working.

SELECT string_name FROM table_name;

This is giving me required output. Like

This is string one.

This is string two.

This is string three.

and so on...

But if I am running a query like this

SELECT * FROM table_name WHERE string_name='This is string one'

It's not giving any output. I even tried TRIM function.

SELECT * FROM table_name WHERE TRIM(string_name)=TRIM('This is string one')

But it's still not giving any output.

Please suggest what I am missing here. Is it because of some formatting or am I doing any silly mistake. By the way, Strings are saved as VARCHAR in the database.


问:
Sharing the same settings.xml maven configuration for the whole team
We have a very big maven configuration with very many repositories, plugin repositories, and various other things.

We always end up having to manually copy/paste the same file to other team members, and then replace the username and password.

I was curious if anyone is aware of an automated solution for sharing the settings.xml file ?

Something that will pull the configuration or part of the configuration from git ?

If I had to write it myself I would probably use a script and git, to pull changes, do replacements, and replace the current settings file.

But it's better to see if someone has already made this.

We also have a different proxy username and password for each user.
We use both nexus, and also a proxy.

答:
Tomtit is good with that type of tasks, just include this small helper into your scm:

.tom/mvn-settings.pl6

```<code>#!perl6

my $user = prompt "username ";
my $password = prompt "password ";

directory '/tmp/mvn';

# load settings template from other repository

git-scm 'https://scm/repo/mvn-files', %( to => '/tmp/mvn' );

template-create 'settings.xml', %(
  source => ( slurp '/tmp/mvn/settings.tmpl' ),
  mode => '644',
  variables => %(
    user => $user,
    password => $password
  ),
);
</code>```

The run it:

```<code>tom mvn-settings
</code>```

Body:
Tomtit is good with that type of tasks, just include this small helper into your scm:

.tom/mvn-settings.pl6

#!perl6

my $user = prompt "username ";
my $password = prompt "password ";

directory '/tmp/mvn';

# load settings template from other repository

git-scm 'https://scm/repo/mvn-files', %( to => '/tmp/mvn' );

template-create 'settings.xml', %(
  source => ( slurp '/tmp/mvn/settings.tmpl' ),
  mode => '644',
  variables => %(
    user => $user,
    password => $password
  ),
);

The run it:

tom mvn-settings


问:
How to read annotation value in play framework templates?
I want to use values from annotation in CRUD module templates, to utilize HTML5 functions.

e.g.

@Range(min=0, max=10)

public int size;

CRUD module use views/tags/crud/numberField.html to display number field:

```<code>#{field 'object.' + _name}
    <label for="${field.id}">
        &{_name}
    </label>
    <input id="${field.id}" type="text" name="${field.name}" value="${params[field.name]?.escape()?.raw() ?: field.error?.message == 'validation.required' ? '' : _value?.escape()?.raw()}" size="5" />
    #{ifError field.name}
        <span class="error">${field.error}</span>
    #{/ifError}
#{/field}
</code>```

How can I read min/max value from annotation then output as min="0" max="0" in <input> ?

答:
You can do this by adding methods to the CRUD module's CRUD.ObjectType.ObjectField inner class that read the annotation values, e.g. something like:

```<code>public String getRangeMin() {
    if (!property.field.isAnnotationPresent(Range.class)) {
        return null;
    }
    return property.field.getAnnotation(Range.class).min();
}
</code>```

Then in crud/views/tags/crud/form.html you can use this in a new tag parameter inside the #{if field.type == 'number'} (note that field is a CRUD.ObjectType.ObjectField here:

```<code>#{crud.numberField min:field.min …
</code>```

The value is then available as _min inside the numberField.html tag.

ContentLicense: CC BY-SA 3.0

Body:
I want to use values from annotation in CRUD module templates, to utilize HTML5 functions.

e.g.

@Range(min=0, max=10)

public int size;

CRUD module use views/tags/crud/numberField.html to display number field:

#{field 'object.' + _name}

        &{_name}

    <input id="${field.id}" type="text" name="${field.name}" value="${params[field.name]?.escape()?.raw() ?: field.error?.message == 'validation.required' ? '' : _value?.escape()?.raw()}" size="5" />
    #{ifError field.name}
        ${field.error}
    #{/ifError}
#{/field}

How can I read min/max value from annotation then output as min="0" max="0" in <input> ?

Body:
You can do this by adding methods to the CRUD module's CRUD.ObjectType.ObjectField inner class that read the annotation values, e.g. something like:

public String getRangeMin() {
    if (!property.field.isAnnotationPresent(Range.class)) {
        return null;
    }
    return property.field.getAnnotation(Range.class).min();
}

Then in crud/views/tags/crud/form.html you can use this in a new tag parameter inside the #{if field.type == 'number'} (note that field is a CRUD.ObjectType.ObjectField here:

#{crud.numberField min:field.min …

The value is then available as _min inside the numberField.html tag.


问:
How to compare mp3 programmatically
I like to be able to compare mp3’s programmatically. The problem I don’t know by what.
Header? Histogram? channels? Does anyone have experience with this subject?</p>

答:
It looks like Chromaprint would do what you're looking for. It transforms PCM data in audio fingerprints which you can then use to compare.

They have a C API library (it's actually written in C++, though), a python front end, and also some utilities to convert the results in JSON which means you could use another language to manipulate the data. I don't think that they provide the compare function itself, though.

Also if you're using a Linux system, it's likely that you will find a package for it.

ContentLicense: CC BY-SA 2.5

Title: How to compare mp3 programmatically

LastEditorDisplayName: brian d foy


问:
How do I get this program to print out the contents of a list in a list?
I'm still a beginner at python, but I've been trying to get better at it lately. I'm trying to create a program that asks the user what day it is and what they have to do. It will then take this and place it in a list. I'm trying to get the program to print out the list that has the new assignment in it, but it's not working. (The list that has the assignment is in another list.)

I tried placing it all in a function and using a return stmt, but it says that "the object is not callable". I also tried normally printing it out with a print stmt, but it doesn't work.

```<code>#List of days
doa = ["M","T","W","TH","F","S","SU"]

#Lists for every day
my_list = []
for i in range(7):
    my_list.append([i])

#Ask user what today is
day = input("What is the day today?")

#Ask user assignment
ast = input("What do you have to do my sir?")

#Add to list
if day == doa[i]:
    my_list[i].append(ast)

#Print that days list to check
print(my_list(day))
</code>```

I know what I'm doing is wrong. I'm assuming the way I'm doing it prints out the index for the list (that's in another list)...,but I couldn't think of any other way.

答:
You can certainly do this using lists. Your approach of accessing the variables within the lists and even setting up your list of lists is likely what is tripping you up.

```<code>>>> doa = ["M","T","W","TH","F","S","SU"]
>>> my_list = [[day] for day in doa]
>>> my_list
[['M'], ['T'], ['W'], ['TH'], ['F'], ['S'], ['SU']]
>>> day = input("What is the day today?")
What is the day today?M
>>> ast = input("What do you have to do my sir?")
What do you have to do my sir?Too much
>>> for d in my_list:
...     if d[0] == day:
...         d.append(ast)
...
>>> my_list
[['M', 'Too much'], ['T'], ['W'], ['TH'], ['F'], ['S'], ['SU']]
</code>```

What might be a better approach is to use a dictionary. This simplifies your code (and is generally more efficient) by providing named access to your lists.

```<code>>>> doa = ["M","T","W","TH","F","S","SU"]
>>> my_list = {day: [] for day in doa}
>>> my_list
{'M': [], 'T': [], 'W': [], 'TH': [], 'F': [], 'S': [], 'SU': []}
>>> day = input("What is the day today?")
What is the day today?M
>>> day
'M'
>>> ast = input("What do you have to do my sir?")
What do you have to do my sir?Too much
>>> ast
'Too much'
>>> my_list[day].append(ast)
>>> my_list[day]
['Too much']
>>> my_list
{'M': ['Too much'], 'T': [], 'W': [], 'TH': [], 'F': [], 'S': [], 'SU': []}
</code>```

Body:
I'm still a beginner at python, but I've been trying to get better at it lately. I'm trying to create a program that asks the user what day it is and what they have to do. It will then take this and place it in a list. I'm trying to get the program to print out the list that has the new assignment in it, but it's not working. (The list that has the assignment is in another list.)

I tried placing it all in a function and using a return stmt, but it says that "the object is not callable". I also tried normally printing it out with a print stmt, but it doesn't work.

#List of days
doa = ["M","T","W","TH","F","S","SU"]

#Lists for every day
my_list = []
for i in range(7):
    my_list.append([i])

#Ask user what today is
day = input("What is the day today?")

#Ask user assignment
ast = input("What do you have to do my sir?")

#Add to list
if day == doa[i]:
    my_list[i].append(ast)

#Print that days list to check
print(my_list(day))

I know what I'm doing is wrong. I'm assuming the way I'm doing it prints out the index for the list (that's in another list)...,but I couldn't think of any other way.

Body:
You can certainly do this using lists. Your approach of accessing the variables within the lists and even setting up your list of lists is likely what is tripping you up.

>>> doa = ["M","T","W","TH","F","S","SU"]
>>> my_list = [[day] for day in doa]
>>> my_list
[['M'], ['T'], ['W'], ['TH'], ['F'], ['S'], ['SU']]
>>> day = input("What is the day today?")
What is the day today?M
>>> ast = input("What do you have to do my sir?")
What do you have to do my sir?Too much
>>> for d in my_list:
...     if d[0] == day:
...         d.append(ast)
...
>>> my_list
[['M', 'Too much'], ['T'], ['W'], ['TH'], ['F'], ['S'], ['SU']]

What might be a better approach is to use a dictionary. This simplifies your code (and is generally more efficient) by providing named access to your lists.

>>> doa = ["M","T","W","TH","F","S","SU"]
>>> my_list = {day: [] for day in doa}
>>> my_list
{'M': [], 'T': [], 'W': [], 'TH': [], 'F': [], 'S': [], 'SU': []}
>>> day = input("What is the day today?")
What is the day today?M
>>> day
'M'
>>> ast = input("What do you have to do my sir?")
What do you have to do my sir?Too much
>>> ast
'Too much'
>>> my_list[day].append(ast)
>>> my_list[day]
['Too much']
>>> my_list
{'M': ['Too much'], 'T': [], 'W': [], 'TH': [], 'F': [], 'S': [], 'SU': []}


问:
Solving 2nd order differential equations wrt this code
I cannot write the program which is solving 2nd order differential equation with respect to code I wrote for y'=y

I know that I should write a program which turn a 2nd order differential equation into two ordinary differential equations but I don!t know how can I do in Python.

P.S. : I have to use that code below. It's a homework

Please forgive my mistakes, it's my first question. Thanks in advance

from pylab import*
xd=[];y=[]
def F(x,y):
    return y
def rk4(x0,y0,h,N):
    xd.append(x0)
    yd.append(y0)
    for i in range (1,N+1) :
        k1=F(x0,y0)
        k2=F(x0+h/2,y0+h/2*k1)
        k3=F(x0+h/2,y0+h/2*k2)
        k4=F(x0+h,y0+h*k3)
        k=1/6*(k1+2*k2+2*k3+k4)
        y=y0+h*k
        x=x0+h
        yd.append(y)
        xd.append(x)
        y0=y
        x0=x
    return xd,yd
x0=0
y0=1
h=0.1
N=10
x,y=rk4(x0,y0,h,N)
print("x=",x)
print("y=",y)
plot(x,y)
show()
```

答:
You can basically reformulate any scalar ODE (Ordinary Differential Equation) of order n in Cauchy form into an ODE of order 1. The only thing that you "pay" in this operation is that the second ODE's variables will be vectors instead of scalar functions.

Let me give you an example with an ODE of order 2. Suppose your ODE is: y'' = F(x,y, y'). Then you can replace it by [y, y']' = [y', F(x,y,y')], where the derivative of a vector has to be understood component-wise.

Let's take back your code and instead of using Runge-Kutta of order 4 as an approximate solution of your ODE, we will apply a simple Euler scheme.

```<code>from pylab import*
import matplotlib.pyplot as plt

# we are approximating the solution of y' = f(x,y) for x in [x_0, x_1] satisfying the Cauchy condition y(x_0) = y0

def f(x, y0):
    return y0

# here f defines the equation y' = y

def explicit_euler(x0, x1, y0, N,):
    # The following formula relates h and N
    h = (x1 - x0)/(N+1)

    xd = list()
    yd = list()

    xd.append(x0)
    yd.append(y0)

    for i in range (1,N+1) :
        # We use the explicite Euler scheme y_{i+1} = y_i + h * f(x_i, y_i)
        y = yd[-1] + h * f(xd[-1], yd[-1])
        # you can replace the above scheme by any other (R-K 4 for example !)
        x = xd[-1] + h

        yd.append(y)
        xd.append(x)

    return xd, yd

N = 250
x1 = 5
x0 = 0
y0 = 1
# the only function which satisfies y(0) = 1 and y'=y is y(x)=exp(x).
xd, yd =explicit_euler(x0, x1, y0, N)
plt.plot(xd,yd)
plt.show()
# this plot has the right shape !
</code>```

Note that you can replace the Euler scheme by R-K 4 which has better stability and convergence properties.

Now, suppose that you want to solve a second order ODE, let's say for example: y'' = -y with initial conditions y(0) = 1 and y'(0) = 0. Then you have to transform your scalar function y into a vector of size 2 as explained above and in the comments in code below.

```<code>from pylab import*
import matplotlib.pyplot as plt
import numpy as np

# we are approximating the solution of y'' = f(x,y,y') for x in [x_0, x_1] satisfying the Cauchy condition of order 2:
# y(x_0) = y0 and y'(x_0) = y1

def f(x, y_d_0, y_d_1):
    return -y_d_0

# here f defines the equation y'' = -y

def explicit_euler(x0, x1, y0, y1, N,):
    # The following formula relates h and N
    h = (x1 - x0)/(N+1)

    xd = list()
    yd = list()

    xd.append(x0)
    # to allow group operations in R^2, we use the numpy library
    yd.append(np.array([y0, y1]))

    for i in range (1,N+1) :
        # We use the explicite Euler scheme y_{i+1} = y_i + h * f(x_i, y_i)
        # remember that now, yd is a list of vectors

        # the equivalent order 1 equation is [y, y']' = [y', f(x,y,y')]
        y = yd[-1] + h * np.array([yd[-1][1], f(xd[-1], yd[-1][0], yd[-1][1])])  # vector of dimension 2
        print(y)
        # you can replace the above scheme by any other (R-K 4 for example !)

        x = xd[-1] + h  # vector of dimension 1

        yd.append(y)
        xd.append(x)

    return xd, yd

x0 = 0
x1 = 30
y0 = 1
y1 = 0

# the only function satisfying y(0) = 1, y'(0) = 0 and y'' = -y is y(x) = cos(x)
N = 5000
xd, yd =explicit_euler(x0, x1, y0, y1, N)
# I only want the first variable of yd
yd_1 = list(map(lambda y: y[0], yd))

plt.plot(xd,yd_1)
plt.show()
</code>```

Body:
You can basically reformulate any scalar ODE (Ordinary Differential Equation) of order n in Cauchy form into an ODE of order 1. The only thing that you "pay" in this operation is that the second ODE's variables will be vectors instead of scalar functions.

Let me give you an example with an ODE of order 2. Suppose your ODE is: y'' = F(x,y, y'). Then you can replace it by [y, y']' = [y', F(x,y,y')], where the derivative of a vector has to be understood component-wise.

Let's take back your code and instead of using Runge-Kutta of order 4 as an approximate solution of your ODE, we will apply a simple Euler scheme.

from pylab import*
import matplotlib.pyplot as plt

# we are approximating the solution of y' = f(x,y) for x in [x_0, x_1] satisfying the Cauchy condition y(x_0) = y0

def f(x, y0):
    return y0

# here f defines the equation y' = y

def explicit_euler(x0, x1, y0, N,):
    # The following formula relates h and N
    h = (x1 - x0)/(N+1)

    xd = list()
    yd = list()

    xd.append(x0)
    yd.append(y0)

    for i in range (1,N+1) :
        # We use the explicite Euler scheme y_{i+1} = y_i + h * f(x_i, y_i)
        y = yd[-1] + h * f(xd[-1], yd[-1])
        # you can replace the above scheme by any other (R-K 4 for example !)
        x = xd[-1] + h

        yd.append(y)
        xd.append(x)

    return xd, yd

N = 250
x1 = 5
x0 = 0
y0 = 1
# the only function which satisfies y(0) = 1 and y'=y is y(x)=exp(x).
xd, yd =explicit_euler(x0, x1, y0, N)
plt.plot(xd,yd)
plt.show()
# this plot has the right shape !

Note that you can replace the Euler scheme by R-K 4 which has better stability and convergence properties.

Now, suppose that you want to solve a second order ODE, let's say for example: y'' = -y with initial conditions y(0) = 1 and y'(0) = 0. Then you have to transform your scalar function y into a vector of size 2 as explained above and in the comments in code below.

from pylab import*
import matplotlib.pyplot as plt
import numpy as np

# we are approximating the solution of y'' = f(x,y,y') for x in [x_0, x_1] satisfying the Cauchy condition of order 2:
# y(x_0) = y0 and y'(x_0) = y1

def f(x, y_d_0, y_d_1):
    return -y_d_0

# here f defines the equation y'' = -y

def explicit_euler(x0, x1, y0, y1, N,):
    # The following formula relates h and N
    h = (x1 - x0)/(N+1)

    xd = list()
    yd = list()

    xd.append(x0)
    # to allow group operations in R^2, we use the numpy library
    yd.append(np.array([y0, y1]))

    for i in range (1,N+1) :
        # We use the explicite Euler scheme y_{i+1} = y_i + h * f(x_i, y_i)
        # remember that now, yd is a list of vectors

        # the equivalent order 1 equation is [y, y']' = [y', f(x,y,y')]
        y = yd[-1] + h * np.array([yd[-1][1], f(xd[-1], yd[-1][0], yd[-1][1])])  # vector of dimension 2
        print(y)
        # you can replace the above scheme by any other (R-K 4 for example !)

        x = xd[-1] + h  # vector of dimension 1

        yd.append(y)
        xd.append(x)

    return xd, yd

x0 = 0
x1 = 30
y0 = 1
y1 = 0

# the only function satisfying y(0) = 1, y'(0) = 0 and y'' = -y is y(x) = cos(x)
N = 5000
xd, yd =explicit_euler(x0, x1, y0, y1, N)
# I only want the first variable of yd
yd_1 = list(map(lambda y: y[0], yd))

plt.plot(xd,yd_1)
plt.show()


问:
Get non matching record
I have two views. Both the views have most of the columns same. View1 has 20 columns and View2 has 22 columns. View2 has 20 columns same as View1.
Now I want a query to find out if the data in these common 20 columns is the same or not and if not I would like to get those records

View1

```<code>Columns FN  LN  EmpID
    a   b   1
    c   d   2
</code>```

View2

```<code>Columns FN  LN  EmpID
    a   b   1
    c   b   2
</code>```

I want a query where I can check if there is any mismatch in column values  between View1 and View2 and if there is a mismatch than return that record. Like the query should return View2's second record because it does not match with View1 second record

答:
You can use EXCEPT instead of having to JOIN against all of the columns. This will give you everything from View1 that is not matched in View2:</p>

```<code>SELECT [Col1], [Col2], [Col5]
FROM VIEW1
EXCEPT
SELECT [Col1], [Col2], [Col5]
FROM VIEW2
</code>```

Title: Get non matching record

Body:
I have two views. Both the views have most of the columns same. View1 has 20 columns and View2 has 22 columns. View2 has 20 columns same as View1.
Now I want a query to find out if the data in these common 20 columns is the same or not and if not I would like to get those records

View1

Columns FN  LN  EmpID
    a   b   1
    c   d   2

View2

Columns FN  LN  EmpID
    a   b   1
    c   b   2

I want a query where I can check if there is any mismatch in column values  between View1 and View2 and if there is a mismatch than return that record. Like the query should return View2's second record because it does not match with View1 second record

Body:
You can use EXCEPT instead of having to JOIN against all of the columns. This will give you everything from View1 that is not matched in View2:

SELECT [Col1], [Col2], [Col5]
FROM VIEW1
EXCEPT
SELECT [Col1], [Col2], [Col5]
FROM VIEW2


问:
Thymeleaf Option Without Selection
From the controller, I have returned an object containing a list of objects. I want to display these list of objects in the dropdown with no pre-selection(or default value i.e. "Select Dish"), but dropdown is shown with pre-selected last value in the list.

Controller:

```<code>@GetMapping(path = "/createOrder")
public ModelAndView displayOrder(OrderFormDetails order) {
    ModelAndView mav = new ModelAndView();
    mav.addObject("order", orderService.displayOrder());
    mav.setViewName("createOrder");
    return mav;
}
</code>```

Model:

```<code>public class OrderFormDetails {

    @NotEmpty(message = "*Please provide your name")
    private String name;

    @NotEmpty(message = "*Please provide your address")
    private String address;

    private List < Dish > dishes;
</code>```

View:

```<code><select class="form-control" th:field="*{dishes}" id="dropOperator">
    <option value="" selected="selected">Sélect dish</option>
    <option th:each="dish, itemStat : *{dishes}" th:value="*{dishes[__${itemStat.index}__].id}" th:text="*{dishes[__${itemStat.index}__].title}">
    </option>
</select>
</code>```

I have tried multiple tricks, but none of them worked. Thanks...

答:
Usually you don't want to mix possible options and selected option together within one field (as you apparently did). All you need to do is to decouple those things. Possible steps may be helpful:

Since OrderFormDetails acts like your form backing bean, it should contain a placeholder for selected value (Dish.id) instead of List with possible dishes. Change your OrderFormDetails to the following:

```<code>public class OrderFormDetails {

    @NotEmpty(message = "*Please provide your name")
    private String name;

    @NotEmpty(message = "*Please provide your address")
    private String address;

    private T selectedDish;

    // getters, setters, rest of the class omitted

</code>```

...where T is the type assigned to Dish.id field.

Possible (selectable) dishes should be provided separately as a model attribute. Add following line to your displayOrder method:

```<code>mav.addObject("dishes", getDishes());
</code>```

...where getDishes() returns List<Dish> containing all dishes being an option for an user.

Adjust your view to work with updated approach:

```<code><select class="form-control" th:field="*{selectedDish}" id="dropOperator">
    <option value="" selected="selected">Sélect dish</option>
    <option th:each="dish : ${dishes}" th:value="${dish.id}" th:text="${dish.title}">
    </option>
</select>
</code>```

That's all. Such an approach is also shown in documentation - th:field on <select> level refers to form backing bean's  field, whereas <option> elements are created out of separate collection provided as model attribute.

Title: Thymeleaf Option Without Selection

Body:
From the controller, I have returned an object containing a list of objects. I want to display these list of objects in the dropdown with no pre-selection(or default value i.e. "Select Dish"), but dropdown is shown with pre-selected last value in the list.

Controller:

@GetMapping(path = "/createOrder")
public ModelAndView displayOrder(OrderFormDetails order) {
    ModelAndView mav = new ModelAndView();
    mav.addObject("order", orderService.displayOrder());
    mav.setViewName("createOrder");
    return mav;
}

Model:

public class OrderFormDetails {

    @NotEmpty(message = "*Please provide your name")
    private String name;

    @NotEmpty(message = "*Please provide your address")
    private String address;

    private List < Dish > dishes;

View:

<select class="form-control" th:field="*{dishes}" id="dropOperator">
    <option value="" selected="selected">Sélect dish</option>
    <option th:each="dish, itemStat : *{dishes}" th:value="*{dishes[__${itemStat.index}__].id}" th:text="*{dishes[__${itemStat.index}__].title}">
    </option>
</select>

I have tried multiple tricks, but none of them worked. Thanks...

Body:
Usually you don't want to mix possible options and selected option together within one field (as you apparently did). All you need to do is to decouple those things. Possible steps may be helpful:

Since OrderFormDetails acts like your form backing bean, it should contain a placeholder for selected value (Dish.id) instead of List with possible dishes. Change your OrderFormDetails to the following:

public class OrderFormDetails {

    @NotEmpty(message = "*Please provide your name")
    private String name;

    @NotEmpty(message = "*Please provide your address")
    private String address;

    private T selectedDish;

    // getters, setters, rest of the class omitted

...where T is the type assigned to Dish.id field.

Possible (selectable) dishes should be provided separately as a model attribute. Add following line to your displayOrder method:

mav.addObject("dishes", getDishes());

...where getDishes() returns List<Dish> containing all dishes being an option for an user.

Adjust your view to work with updated approach:

<select class="form-control" th:field="*{selectedDish}" id="dropOperator">
    <option value="" selected="selected">Sélect dish</option>
    <option th:each="dish : ${dishes}" th:value="${dish.id}" th:text="${dish.title}">
    </option>
</select>

That's all. Such an approach is also shown in documentation - th:field on <select> level refers to form backing bean's  field, whereas <option> elements are created out of separate collection provided as model attribute.


问:
Playing a Sound Notification when Specific Text on Page Appears
I'm trying to figure out a way to play a sound notification whenever the phrase "2 credits" appears in the top right corner on a specific website at: https://www.submithub.com/. As it stands, that specific area of the site oscillates between "0 credits" and "2 credits" depending on if you've submitted to the site within the last few hours. Once you are able to submit again, the text changes to "2 credits."

I have also provided a screenshot of what I am talking about:

I have been using code primarily derived from the following StackOverflow thread: How can I have a Tampermonkey userscript play a sound when a specific word appears on a page?

Here is the code that I am working with:

```<code>// ==UserScript==
// @name     SubmitHub Notification
// @include  https://www.submithub.com/
// @grant    none
// ==/UserScript==
/* eslint-disable no-multi-spaces */

//-- Set the watched terms using the awesome power of regex.
var watchRegx = /\b2 credits\b/i;
var alrtSound = new Audio ("data:audio/mp3;base64,[encoded data, 5072 characters]");

//-- Customize this next for your page or get lazy and use "body".
var cntnrNode = document.querySelector ("#mainArea");
if (typeof cntnrNode === "undefined")   console.error ("TM: Container node not found.");
else {
    var wordObsrv = new MutationObserver (alertOnWord);
    wordObsrv.observe (document.body, {childList: true, subtree: true} );
}
function alertOnWord (mutationRecords) {
    mutationRecords.forEach (muttn => {
        if (muttn.type === "childList"  &&  typeof muttn.addedNodes === "object") {
            muttn.addedNodes.forEach (newNode => {
                /*-- Restrict the kinds of nodes watched for better performance
                    and/or to avoid false positives.
                */
                if (newNode.nodeName === "DIV"  ||  newNode.nodeName === "SPAN"  ||  newNode.nodeName === "P") {
                    if (watchRegx.test (newNode.textContent) ) {
                        console.log ("Found new instance of target term!");
                        alrtSound.play ();
                    }
                }
            } );
        }
    } );
}
</code>```

As it stands, I cannot get "2 credits" to make any notification sounds via Regex, such as shown below, but I have been able to get just "credits" to work:

```<code>var watchRegx = /\b2 credits\b/i;
</code>```

Here is the HTML of the specific part of the page where "2 credits" lies on the site:

```<code><span class="grey black-text lighten-2 credit-counter"><span class="remaining">2</span> credits</span>
</code>```

The nature of the HTML indicates that this might not be as simple as using a Regex with "2 credits." Maybe there is an easy solution. Any and all advice would be wonderful. Thanks in advance.

答:
Here, we might want to separately capture our desired substrings then replace it:

```<code>.+?<span class="remaining">([0-9]+)?<\/span>(.+?)<\/span>
</code>```

Our desired digits are in this capturing group:

```<code>([0-9]+)
</code>```

and the second part is in this group:

```<code>(.+?)
</code>```

Test

const regex = /.+?([0-9]+)?<\/span>(.+?)<\/span>/gm;
const str = `<span class="grey black-text lighten-2 credit-counter"><span class="remaining">2</span> credits</span>`;
const subst = `$1$2`;

// The substituted value will be contained in the result variable
const result = str.replace(regex, subst);

console.log(result);```

DEMO

Body:
I'm trying to figure out a way to play a sound notification whenever the phrase "2 credits" appears in the top right corner on a specific website at: https://www.submithub.com/. As it stands, that specific area of the site oscillates between "0 credits" and "2 credits" depending on if you've submitted to the site within the last few hours. Once you are able to submit again, the text changes to "2 credits."

I have also provided a screenshot of what I am talking about:

I have been using code primarily derived from the following StackOverflow thread: How can I have a Tampermonkey userscript play a sound when a specific word appears on a page?

Here is the code that I am working with:

// ==UserScript==
// @name     SubmitHub Notification
// @include  https://www.submithub.com/
// @grant    none
// ==/UserScript==
/* eslint-disable no-multi-spaces */

//-- Set the watched terms using the awesome power of regex.
var watchRegx = /\b2 credits\b/i;
var alrtSound = new Audio ("data:audio/mp3;base64,[encoded data, 5072 characters]");

//-- Customize this next for your page or get lazy and use "body".
var cntnrNode = document.querySelector ("#mainArea");
if (typeof cntnrNode === "undefined")   console.error ("TM: Container node not found.");
else {
    var wordObsrv = new MutationObserver (alertOnWord);
    wordObsrv.observe (document.body, {childList: true, subtree: true} );
}
function alertOnWord (mutationRecords) {
    mutationRecords.forEach (muttn => {
        if (muttn.type === "childList"  &&  typeof muttn.addedNodes === "object") {
            muttn.addedNodes.forEach (newNode => {
                /*-- Restrict the kinds of nodes watched for better performance
                    and/or to avoid false positives.
                */
                if (newNode.nodeName === "DIV"  ||  newNode.nodeName === "SPAN"  ||  newNode.nodeName === "P") {
                    if (watchRegx.test (newNode.textContent) ) {
                        console.log ("Found new instance of target term!");
                        alrtSound.play ();
                    }
                }
            } );
        }
    } );
}

As it stands, I cannot get "2 credits" to make any notification sounds via Regex, such as shown below, but I have been able to get just "credits" to work:

var watchRegx = /\b2 credits\b/i;

Here is the HTML of the specific part of the page where "2 credits" lies on the site:

2 credits

The nature of the HTML indicates that this might not be as simple as using a Regex with "2 credits." Maybe there is an easy solution. Any and all advice would be wonderful. Thanks in advance.

Body:
Here, we might want to separately capture our desired substrings then replace it:

.+?<span class="remaining">([0-9]+)?<\/span>(.+?)<\/span>

Our desired digits are in this capturing group:

([0-9]+)

and the second part is in this group:

(.+?)

Test

const regex = /.+?<span class="remaining">([0-9]+)?<\/span>(.+?)<\/span>/gm;
const str = `<span class="grey black-text lighten-2 credit-counter"><span class="remaining">2</span> credits</span>`;
const subst = `$1$2`;

// The substituted value will be contained in the result variable
const result = str.replace(regex, subst);

console.log(result);

DEMO


问:
What's the best way of parsing strings?
We've got a scenario that requires us to parse lots of e-mail (plain text), each e-mail 'type' is the result of a script being run against various platforms. Some are tab delimited, some are space delimited, some we simply don't know yet.

We'll need to support more 'formats' in the future too.

Do we go for a solution using:

Regex

Simply string searching (using string.IndexOf etc)

Lex/ Yacc

Other

The overall solution will be developed in C# 2.0 (hopefully 3.5)

答:
Regex.

Regex can solve almost everything except for world peace.  Well maybe world peace too.

Title: What's the best way of parsing strings?

LastEditorDisplayName: Torsten Marek

OwnerDisplayName: IainMH


问:
to replace using find word in array from text file
I have problem that str_replace can't replace the second to last word... first word is working then second up to last is not work in array.. I tried enter the message "ducker apple banana chicken" in "chat.php?message=" then become like this:

output:

"***er apple banana chicken"

badwords.txt:

```<code>duck;
apple;
banana;
chicken;
water;
</code>```

chat.php

```<code>$censoredfilter = file("badwords.txt");
$censoredfilter = implode("\n", $censoredfilter);
$censoredfilter = explode(";", $censoredfilter);

$message = $_GET['message'];

for($i = 0; $i<sizeof($censoredfilter);$i++)
{
    $message = str_replace($censoredfilter[$i], "***", $message);
}
</code>```

答:
Incorrect usage of implode there no?

```<code>$censoredfilter = file_get_contents("badwords.txt");
$censoredfilter = explode(";\n", $censoredfilter);
</code>```

Alternatively,

```<code>$censoredfilter = file_get_contents("badwords.txt");
$censoredfilter = str_replace(array("\r", "\n"), '', $censoredfilter);
$censoredfilter = explode(";", $censoredfilter);
</code>```

Body:
I have problem that str_replace can't replace the second to last word... first word is working then second up to last is not work in array.. I tried enter the message "ducker apple banana chicken" in "chat.php?message=" then become like this:

output:

"***er apple banana chicken"

badwords.txt:

duck;
apple;
banana;
chicken;
water;

chat.php

$censoredfilter = file("badwords.txt");
$censoredfilter = implode("\n", $censoredfilter);
$censoredfilter = explode(";", $censoredfilter);

$message = $_GET['message'];

for($i = 0; $i<sizeof($censoredfilter);$i++)
{
    $message = str_replace($censoredfilter[$i], "***", $message);
}

Body:
Incorrect usage of implode there no?

$censoredfilter = file_get_contents("badwords.txt");
$censoredfilter = explode(";\n", $censoredfilter);

Alternatively,

$censoredfilter = file_get_contents("badwords.txt");
$censoredfilter = str_replace(array("\r", "\n"), '', $censoredfilter);
$censoredfilter = explode(";", $censoredfilter);


问:
ASP.NET core label taghelper. How to append custom text
When we write

```<code><label asp-for="Email"></label>
</code>```

it generates the following HTML:

```<code><label for="Email">Email Address</label>
</code>```

It works fine. The question is whether it's possible to extend tag helper to support custom text to be added? For example, if I write

```<code><label asp-for="Email" asp-postfix=":"></label>
</code>```

it generates the following HTML:

```<code><label for="Email">Email Address:</label>
</code>```

Please see that colon is added now to the label text. And colon could be replaced with any other text.

答:
This works nicely:</p>

```<code><form method="post" class="container mt-3 backgroundwhite w-100">
   <div class="form-group row">
      <label class="col-4 text-right pr-1" style="" asp-for="ServiceToBeAdded.Name"></label><span>:  </span>
      <input class="form-control col-6" asp-for="ServiceToBeAdded.Name" type="text" />
  </div>
  <div class="form-group row">
    <label class="col-4 text-right pr-1" asp-for="ServiceToBeAdded.Price"></label><span>:  </span>
    <input class="form-control col-6" asp-for="ServiceToBeAdded.Price" type="text" />
  </div>

</form>
</code>```

Body:
When we write

it generates the following HTML:

Email Address

It works fine. The question is whether it's possible to extend tag helper to support custom text to be added? For example, if I write

it generates the following HTML:

Email Address:

Please see that colon is added now to the label text. And colon could be replaced with any other text.

Body:
This works nicely:

<form method="post" class="container mt-3 backgroundwhite w-100">
   <div class="form-group row">
      <label class="col-4 text-right pr-1" style="" asp-for="ServiceToBeAdded.Name"></label><span>: &nbsp;</span>
      <input class="form-control col-6" asp-for="ServiceToBeAdded.Name" type="text" />
  </div>
  <div class="form-group row">
    <label class="col-4 text-right pr-1" asp-for="ServiceToBeAdded.Price"></label><span>: &nbsp;</span>
    <input class="form-control col-6" asp-for="ServiceToBeAdded.Price" type="text" />
  </div>

</form>


问:
RestSharp - Ignore SSL errors
Is there any whay that I can get RestSharp to ignore errors in SSL certificates? I have a test client, and the service I connect to does not yet have a valid cetificate.

When I make a request now I get the error:

```<code>The underlying connection was closed: Could not establish trust
relationship for the SSL/TLS secure channel.
</code>```

答:
You can bypass ssl check

In object level:

(Using RestSharp v106.0.0 but before v107)

//bypass ssl validation check by using RestClient object
var restClient = new RestClient(baseUrl);
restClient.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
```
<p><strong>(Using RestSharp 107 according to the migration guide)</strong></p>
<pre class="lang-cs prettyprint-override"><code>//bypass ssl validation check by using RestClient object
var options = new RestClientOptions(baseurl) {
    RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
};
var restClient = new RestClient(options);
</code>```

OR

In application level:

//bypass ssl validation check globally for whole application.
ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;
```

Title: RestSharp - Ignore SSL errors

Body:
Is there any whay that I can get RestSharp to ignore errors in SSL certificates? I have a test client, and the service I connect to does not yet have a valid cetificate.

When I make a request now I get the error:

The underlying connection was closed: Could not establish trust
relationship for the SSL/TLS secure channel.

Body:
You can bypass ssl check

In object level:

(Using RestSharp v106.0.0 but before v107)

//bypass ssl validation check by using RestClient object
var restClient = new RestClient(baseUrl);
restClient.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;

(Using RestSharp 107 according to the migration guide)

//bypass ssl validation check by using RestClient object
var options = new RestClientOptions(baseurl) {
    RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
};
var restClient = new RestClient(options);

OR

In application level:

//bypass ssl validation check globally for whole application.
ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;


问:
Can I generate a payment URL with Stripe Checkout?
I'd like to create a URL that I can share in my newsletter that sends people directly to a Stripe Checkout form to make a small (fixed amount) payment.

With the new Stripe Checkout I can generate the HTML Code to build a button that I can include in a website. I'd like to avoid sending people to a website where they have to click that button, but send them straight to the payment form based on the parameters in a URL. Is this possible?

答:
Yes,

This can be done with a custom script on your end. As mentioned earlier each page has a unique ID used for tracking, therefore it cant be reused.

But with something like a simple PHP script which initiates this payment you can surely use the URL to the php script as a "constant" url to the payment.

The php would and JS would look something like this after having imported the stripe PHP SDK using composer and stripe.js

```<code><?php
$stripecheckout = \Stripe\Checkout\Session::create([
  'success_url' => 'https://success.url',
  'cancel_url' => 'https://cancel.url',
  'payment_method_types' => ['card'],
  'line_items' => [
    [
      'amount' => 100,
      'currency' => 'usd',
      'name' => '1 item',
      'description' => 'This is my item description',
      'quantity' => 1,
    ],
  ]
]);
 ?>
</code>```

and then this javascript

```<code> <script>
 var stripe = Stripe('pk_test_XXXXXXXXXXXXXXX');
 stripe.redirectToCheckout({
 sessionId: '<?php echo $stripecheckout->id; ?>'
 }).then(function (result) {
   // If `redirectToCheckout` fails due to a browser or network
   // error, display the localized error message to your customer
   // using `result.error.message`.
 });
 </script>
</code>```

This will require some customization and error handling from your end, but in my opinion would be the best solution

Body:
Yes,

This can be done with a custom script on your end. As mentioned earlier each page has a unique ID used for tracking, therefore it cant be reused.

But with something like a simple PHP script which initiates this payment you can surely use the URL to the php script as a "constant" url to the payment.

The php would and JS would look something like this after having imported the stripe PHP SDK using composer and stripe.js

<?php
$stripecheckout = \Stripe\Checkout\Session::create([
  'success_url' => 'https://success.url',
  'cancel_url' => 'https://cancel.url',
  'payment_method_types' => ['card'],
  'line_items' => [
    [
      'amount' => 100,
      'currency' => 'usd',
      'name' => '1 item',
      'description' => 'This is my item description',
      'quantity' => 1,
    ],
  ]
]);
 ?>

and then this javascript

 <script>
 var stripe = Stripe('pk_test_XXXXXXXXXXXXXXX');
 stripe.redirectToCheckout({
 sessionId: '<?php echo $stripecheckout->id; ?>'
 }).then(function (result) {
   // If `redirectToCheckout` fails due to a browser or network
   // error, display the localized error message to your customer
   // using `result.error.message`.
 });
 </script>

This will require some customization and error handling from your end, but in my opinion would be the best solution


问:
s3cmd ERROR: S3 error: 301 - Upload files
s3cmd ERROR: S3 error: 301 (PermanentRedirect).

To files uploads or subpath list, using s3cmd command line.

apt-get update && apt-get install -y python s3cmd

Try specific region but not worked.

Command line:

s3cmd ls  s3://bucket-my-name-sp/hello/ --region sa-east-1

Or

s3cmd put object s3://backup-mobiauto-sp/hello/object  --region sa-east-1

s3cmd ERROR: S3 error: 301 (PermanentRedirect): The bucket you are attempting to access must be addressed using the specified endpoint. Please send all future requests to this endpoint.

答:
Issue Resolved!

How I am using Docker, changed the lines and it worked.

```<code>RUN apt-get update && apt-get install -y wget python python3 python3-pip
RUN pip3 install --upgrade setuptools
RUN wget https://github.com/s3tools/s3cmd/releases/download/v2.0.2/s3cmd-2.0.2.tar.gz -P /tmp
RUN tar xvzf /tmp/s3cmd-2.0.2.tar.gz -C /tmp
RUN cd /tmp/s3cmd-2.0.2/ && python3 setup.py install
</code>```

Return OK:

```<code>s3cmd ls s3://bucket-my-name-sp/hello --recursive
2019-05-27 13:57 253906017   s3://bucket-my-name-sp/hello/physical/2019-05-27-10-57.tar.gz
</code>```

Body:
Issue Resolved!

How I am using Docker, changed the lines and it worked.

RUN apt-get update && apt-get install -y wget python python3 python3-pip
RUN pip3 install --upgrade setuptools
RUN wget https://github.com/s3tools/s3cmd/releases/download/v2.0.2/s3cmd-2.0.2.tar.gz -P /tmp
RUN tar xvzf /tmp/s3cmd-2.0.2.tar.gz -C /tmp
RUN cd /tmp/s3cmd-2.0.2/ && python3 setup.py install

Return OK:

s3cmd ls s3://bucket-my-name-sp/hello --recursive
2019-05-27 13:57 253906017   s3://bucket-my-name-sp/hello/physical/2019-05-27-10-57.tar.gz


问:
WCF Duplex: How to handle thrown exception in duplex Callback
How do I handle an exception thrown in a callback method on the client in a WCF duplex setup?

Currently, the client does not appear to raise the faulted event (unless I'm monitoring it incorrectly?) but any subsequent to call Ping() using the the client fails with CommunicationException: "The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it has been Aborted.".

How do I deal with this and recreate the client etc? My first question is how to find out when it happens. Secondly, how best to deal with it?

My service and callback contracts:

```<code>[ServiceContract(CallbackContract = typeof(ICallback), SessionMode = SessionMode.Required)]
public interface IService
{
    [OperationContract]
    bool Ping();
}

public interface ICallback
{
    [OperationContract(IsOneWay = true)]
    void Pong();
}
</code>```

My server implementation:

```<code>[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single)]
public class Service : IService
{
    public bool Ping()
    {
        var remoteMachine = OperationContext.Current.GetCallbackChannel<ICallback>();

        remoteMachine.Pong();
    }
}
</code>```

My client implementation:

```<code>[CallbackBehavior(UseSynchronizationContext = false, ConcurrencyMode = ConcurrencyMode.Single)]
public class Client : ICallback
{
    public Client ()
    {
        var context = new InstanceContext(this);
        var proxy = new WcfDuplexProxy<IApplicationService>(context);

        (proxy as ICommunicationObject).Faulted += new EventHandler(proxy_Faulted);

        //First Ping will call the Pong callback. The exception is thrown
        proxy.ServiceChannel.Ping();
        //Second Ping call fails as the client is in Aborted state
        try
        {
            proxy.ServiceChannel.Ping();
        }
        catch (Exception)
        {
            //CommunicationException here
            throw;
        }
    }
    void Pong()
    {
        throw new Exception();
    }

    //These event handlers never get called
    void proxy_Faulted(object sender, EventArgs e)
    {
        Console.WriteLine("client faulted proxy_Faulted");
    }
}
</code>```

答:
As it turns out, you cannot expect the Faulted event to be raised. So, the best way to re-establish the connection is to do it when the subsequent call to Ping() fails:

I'll keep the code simple here:

```<code>public class Client : ICallback
{
    public Client ()
    {
        var context = new InstanceContext(this);
        var proxy = new WcfDuplexProxy<IApplicationService>(context);

        (proxy.ServiceChannel as ICommunicationObject).Faulted +=new EventHandler(ServiceChannel_Faulted);

        //First Ping will call the Pong callback. The exception is thrown
        proxy.ServiceChannel.Ping();
        //Second Ping call fails as the client is in Aborted state
        try
        {
            proxy.ServiceChannel.Ping();
        }
        catch (Exception)
        {
            //Re-establish the connection and try again
            proxy.Abort();
            proxy = new WcfDuplexProxy<IApplicationService>(context);
            proxy.ServiceChannel.Ping();
        }
    }
    /*
    [...The rest of the code is the same...]
    //*/
}
</code>```

Obviously, in my example code, the Exception will be thrown again but I hope this is useful to give people an idea of how to re-establish the connection.

Body:
How do I handle an exception thrown in a callback method on the client in a WCF duplex setup?

Currently, the client does not appear to raise the faulted event (unless I'm monitoring it incorrectly?) but any subsequent to call Ping() using the the client fails with CommunicationException: "The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it has been Aborted.".

How do I deal with this and recreate the client etc? My first question is how to find out when it happens. Secondly, how best to deal with it?

My service and callback contracts:

[ServiceContract(CallbackContract = typeof(ICallback), SessionMode = SessionMode.Required)]
public interface IService
{
    [OperationContract]
    bool Ping();
}

public interface ICallback
{
    [OperationContract(IsOneWay = true)]
    void Pong();
}

My server implementation:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single)]
public class Service : IService
{
    public bool Ping()
    {
        var remoteMachine = OperationContext.Current.GetCallbackChannel<ICallback>();

        remoteMachine.Pong();
    }
}

My client implementation:

[CallbackBehavior(UseSynchronizationContext = false, ConcurrencyMode = ConcurrencyMode.Single)]
public class Client : ICallback
{
    public Client ()
    {
        var context = new InstanceContext(this);
        var proxy = new WcfDuplexProxy<IApplicationService>(context);

        (proxy as ICommunicationObject).Faulted += new EventHandler(proxy_Faulted);

        //First Ping will call the Pong callback. The exception is thrown
        proxy.ServiceChannel.Ping();
        //Second Ping call fails as the client is in Aborted state
        try
        {
            proxy.ServiceChannel.Ping();
        }
        catch (Exception)
        {
            //CommunicationException here
            throw;
        }
    }
    void Pong()
    {
        throw new Exception();
    }

    //These event handlers never get called
    void proxy_Faulted(object sender, EventArgs e)
    {
        Console.WriteLine("client faulted proxy_Faulted");
    }
}

Body:
As it turns out, you cannot expect the Faulted event to be raised. So, the best way to re-establish the connection is to do it when the subsequent call to Ping() fails:

I'll keep the code simple here:

public class Client : ICallback
{
    public Client ()
    {
        var context = new InstanceContext(this);
        var proxy = new WcfDuplexProxy<IApplicationService>(context);

        (proxy.ServiceChannel as ICommunicationObject).Faulted +=new EventHandler(ServiceChannel_Faulted);

        //First Ping will call the Pong callback. The exception is thrown
        proxy.ServiceChannel.Ping();
        //Second Ping call fails as the client is in Aborted state
        try
        {
            proxy.ServiceChannel.Ping();
        }
        catch (Exception)
        {
            //Re-establish the connection and try again
            proxy.Abort();
            proxy = new WcfDuplexProxy<IApplicationService>(context);
            proxy.ServiceChannel.Ping();
        }
    }
    /*
    [...The rest of the code is the same...]
    //*/
}

Obviously, in my example code, the Exception will be thrown again but I hope this is useful to give people an idea of how to re-establish the connection.


问:
Support for object level Tagging in boto3 upload_file method
I want to add tags to the files as I upload them to S3. Boto3 supports specifying tags with put_object method, however considering expected file size, I am using upload_file function which handles multipart uploads. But this function rejects 'Tagging' as keyword argument.

import boto3
client = boto3.client('s3', region_name='us-west-2')
client.upload_file('test.mp4', 'bucket_name', 'test.mp4',
                   ExtraArgs={'Tagging': 'type=test'})

ValueError: Invalid extra_args key 'Tagging', must be one of: ACL, CacheControl, ContentDisposition, ContentEncoding, ContentLanguage, ContentType, Expires, GrantFullControl, GrantRead, GrantReadACP, GrantWriteACP, Metadata, RequestPayer, ServerSideEncryption, StorageClass, SSECustomerAlgorithm, SSECustomerKey, SSECustomerKeyMD5, SSEKMSKeyId, WebsiteRedirectLocation

```

<p>I found a way to make this work by using S3 transfer manager directly and modifying allowed keyword list. </p>

<pre class="lang-py prettyprint-override"><code>from s3transfer import S3Transfer
import boto3

client = boto3.client('s3', region_name='us-west-2')
transfer = S3Transfer(client)
transfer.ALLOWED_UPLOAD_ARGS.append('Tagging')
transfer.upload_file('test.mp4', 'bucket_name', 'test.mp4',
                     extra_args={'Tagging': 'type=test'})
</code>```

Even though this works, I don't think this is the best way. It might create other side effects. Currently I am not able to find correct way to achieve this. Any advice would be great. Thanks.

答:
The S3 Customization Reference — Boto 3 Docs documentation lists valid values for extra_args as:

ALLOWED_UPLOAD_ARGS = ['ACL', 'CacheControl', 'ContentDisposition', 'ContentEncoding', 'ContentLanguage', 'ContentType', 'Expires', 'GrantFullControl', 'GrantRead', 'GrantReadACP', 'GrantWriteACP', 'Metadata', 'RequestPayer', 'ServerSideEncryption', 'StorageClass', 'SSECustomerAlgorithm', 'SSECustomerKey', 'SSECustomerKeyMD5', 'SSEKMSKeyId', 'WebsiteRedirectLocation']

Therefore, this does not appear to be a valid way to specify a tag.

It appears that you might need to call put_object_tagging() to add the tag(s) after creating the object.

Body:
I want to add tags to the files as I upload them to S3. Boto3 supports specifying tags with put_object method, however considering expected file size, I am using upload_file function which handles multipart uploads. But this function rejects 'Tagging' as keyword argument.

import boto3
client = boto3.client('s3', region_name='us-west-2')
client.upload_file('test.mp4', 'bucket_name', 'test.mp4',
                   ExtraArgs={'Tagging': 'type=test'})

ValueError: Invalid extra_args key 'Tagging', must be one of: ACL, CacheControl, ContentDisposition, ContentEncoding, ContentLanguage, ContentType, Expires, GrantFullControl, GrantRead, GrantReadACP, GrantWriteACP, Metadata, RequestPayer, ServerSideEncryption, StorageClass, SSECustomerAlgorithm, SSECustomerKey, SSECustomerKeyMD5, SSEKMSKeyId, WebsiteRedirectLocation

I found a way to make this work by using S3 transfer manager directly and modifying allowed keyword list.

from s3transfer import S3Transfer
import boto3

client = boto3.client('s3', region_name='us-west-2')
transfer = S3Transfer(client)
transfer.ALLOWED_UPLOAD_ARGS.append('Tagging')
transfer.upload_file('test.mp4', 'bucket_name', 'test.mp4',
                     extra_args={'Tagging': 'type=test'})

Even though this works, I don't think this is the best way. It might create other side effects. Currently I am not able to find correct way to achieve this. Any advice would be great. Thanks.