问:
Nexmo: Receiving SMSes
As one new to Nexmo, I found an easy way to receive SMSes using Firebase  here.

After initialising Firebase with:

```<code>firebase init functions
</code>```

you write into the generated index.js:

```<code>const functions = require('firebase-functions');
const admin = require('firebase-admin');

admin.initializeApp();

exports.inboundSMS = functions.https.onRequest(async (req, res) => {
  await admin.database().ref('/msgq').push(req.body);
  res.send(200);
});
</code>```

Then you deploy the code to Firebase  with:

```<code>firebase deploy --only functions
</code>```

which yields a callback URL (webhook) similar to:

```<code>https://us-central1-nexmo-project.cloudfunctions.net/inboundSMS
</code>```

By adding the above URL in the API settings of the Nexmo Dashboard, the messages will be grabbed by Firebase DB.

Now I have two questions.

The first is a licencing problem: the author claims that the Firebase "Pay-as-you-go plan is required to use a third-party API". What does this mean? Isn't the webhook consumer always a third party?  I don't find any useful hint on Firebase site.

The second question regards securing the callback URL. It seems that everyone can send data through the URL, so how can I avoid spamming and peruse of the URL?

答:
Glad you found my post useful.

To answer your questions -

If you are using Nexmo to send an SMS, or any other service that would require you to call a 3rd party API, you would need to use the pay-as-you-go from Firebase.  If you only want to use it as a webhook that would be called from an external source into Firebase, the free tier should be usable.  The difference is in the calling external APIs. Google provides a better explanation of this type of call - https://firebase.google.com/docs/functions/use-cases#integrate_with_third-party_services_and_apis.  Google network calls shouldn't be included in this - one of the benefits of using Firebase.

Securing the webhook has a couple of options.  The first is, it's not an easily discoverable URL, so keeping it private should be the initial line of defense. Nexmo also has a list of IP's that can be whitelisted here - https://help.nexmo.com/hc/en-us/articles/204015053. In the headers you should be able to locate the IP and verify it before allowing it to do anything else, or just kick it out completely.

Let me know if that helps!

Title: Nexmo: Receiving SMSes

Body:
As one new to Nexmo, I found an easy way to receive SMSes using Firebase  here.

After initialising Firebase with:

firebase init functions

you write into the generated index.js:

const functions = require('firebase-functions');
const admin = require('firebase-admin');

admin.initializeApp();

exports.inboundSMS = functions.https.onRequest(async (req, res) => {
  await admin.database().ref('/msgq').push(req.body);
  res.send(200);
});

Then you deploy the code to Firebase  with:

firebase deploy --only functions

which yields a callback URL (webhook) similar to:

https://us-central1-nexmo-project.cloudfunctions.net/inboundSMS

By adding the above URL in the API settings of the Nexmo Dashboard, the messages will be grabbed by Firebase DB.

Now I have two questions.

The first is a licencing problem: the author claims that the Firebase "Pay-as-you-go plan is required to use a third-party API". What does this mean? Isn't the webhook consumer always a third party?  I don't find any useful hint on Firebase site.

The second question regards securing the callback URL. It seems that everyone can send data through the URL, so how can I avoid spamming and peruse of the URL?


来源: stackexchange

问:
how to refactor IEX exchange data calls for grabbing data from api in ruby program
I am using the iex exchange api for grabbing info about stocks. It's working great but my code is very ugly was wondering how to refactor the code.

```<code>stock = IEX::Api::Client.new(
            publishable_token: token,
            endpoint: 'https://sandbox.iexapis.com/v1'
            )
</code>```

This is what is needed to grab the info. The problem is that I have to put the code above in every method that utilizes the api. For instance,

```<code>def self.stock_price(ticker)
        stock = IEX::Api::Client.new(
            publishable_token: token,
            endpoint: 'https://sandbox.iexapis.com/v1'
            )
        company = stock.company(ticker)
        quote = stock.quote(ticker.upcase)
        puts "#{company.company_name}: #{quote.latest_price}"
    end

    def self.week_52_high(ticker)
        stock = IEX::Api::Client.new(
            publishable_token: token,
            endpoint: 'https://sandbox.iexapis.com/v1'
            )
            key_stats = stock.key_stats(ticker)
            puts "52-week high: #{key_stats.week_52_high}"
    end

    def self.week_52_low(ticker)
        stock = IEX::Api::Client.new(
            publishable_token: token,
            endpoint: 'https://sandbox.iexapis.com/v1'
            )
            key_stats = stock.key_stats(ticker)
            puts "52-week low: #{key_stats.week_52_low}"
       end
</code>```

Is there any way to factor that call out to a different file and call the method that way? The code is very repetitive as is. The "stock" variable is what i need to actually work with, should I made that a global variable? I've heard that's a no-no but is this case an exception? Also, where i have

```<code>publishable_token: token,
</code>```

that token variable is actually my actual, hard-coded token, not the "token" variable you see, I simply changed it for security issues.  What should I do instead of hard-coding it? The documentation says to turn it into an environment variable but i dont know what that means. Thanks in advance!

答:
What should I do instead of hard-coding it? The documentation says to
  turn it into an environment variable but i dont know what that means.

An environment variable is a variable whose value is set outside the the application, typically through functionality built into the operating system or shell. You need to check the documentation for your setup to see how to set env vars.

You can get env vars in Ruby through the ENV hash.

```<code>ENV['FOO']
ENV.fetch('FOO') # will raise a KeyError if it is not set instead of just returning nil
</code>```

Rails 5.2 and up have secure credentials that can be used instead. It stores your credentials in an encrypted YAML file that can be checked into source control.

How do I refactor this?

One way to refactor this would be to use delegation instead of bunch of largely static methods:

```<code>require 'forwardable'

class MyClient
  extend Forwardable
  TOKEN = ENV.fetch('IEX_API_TOKEN')
  ENDPOINT = ENV.fetch('IEX_API_ENDPOINT', 'https://sandbox.iexapis.com/v1')

  def_delegators :@client, :company, :quote, :key_stats

  def initialize(publishable_token: TOKEN, endpoint: ENDPOINT, client: nil)
    # This is know as constructor injection and makes it easy to mock out
    # the dependency in tests
    @client = client || IEX::Api::Client.new(publishable_token: TOKEN, endpoint: ENDPOINT)
  end

  def stock_price(ticker)
    company_name = company(ticker).company_name
    price = quote(ticker.upcase).latest_price
    puts "#{company_name}: #{price}"
  end

  def week_52_high(ticker)
    puts "52-week high: #{key_stats(ticker).week_52_high}"
  end

  def week_52_low(ticker)
    puts "52-week low: #{key_stats(ticker).week_52_low}"
  end
end
</code>```

```<code>@client = MyClient.new
@client.week_52_low(ticker)
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I am using the iex exchange api for grabbing info about stocks. It's working great but my code is very ugly was wondering how to refactor the code.

stock = IEX::Api::Client.new(
            publishable_token: token,
            endpoint: 'https://sandbox.iexapis.com/v1'
            )

This is what is needed to grab the info. The problem is that I have to put the code above in every method that utilizes the api. For instance,

def self.stock_price(ticker)
        stock = IEX::Api::Client.new(
            publishable_token: token,
            endpoint: 'https://sandbox.iexapis.com/v1'
            )
        company = stock.company(ticker)
        quote = stock.quote(ticker.upcase)
        puts "#{company.company_name}: #{quote.latest_price}"
    end

    def self.week_52_high(ticker)
        stock = IEX::Api::Client.new(
            publishable_token: token,
            endpoint: 'https://sandbox.iexapis.com/v1'
            )
            key_stats = stock.key_stats(ticker)
            puts "52-week high: #{key_stats.week_52_high}"
    end

    def self.week_52_low(ticker)
        stock = IEX::Api::Client.new(
            publishable_token: token,
            endpoint: 'https://sandbox.iexapis.com/v1'
            )
            key_stats = stock.key_stats(ticker)
            puts "52-week low: #{key_stats.week_52_low}"
       end

Is there any way to factor that call out to a different file and call the method that way? The code is very repetitive as is. The "stock" variable is what i need to actually work with, should I made that a global variable? I've heard that's a no-no but is this case an exception? Also, where i have

publishable_token: token,

that token variable is actually my actual, hard-coded token, not the "token" variable you see, I simply changed it for security issues.  What should I do instead of hard-coding it? The documentation says to turn it into an environment variable but i dont know what that means. Thanks in advance!

Body:
What should I do instead of hard-coding it? The documentation says to
  turn it into an environment variable but i dont know what that means.

An environment variable is a variable whose value is set outside the the application, typically through functionality built into the operating system or shell. You need to check the documentation for your setup to see how to set env vars.

You can get env vars in Ruby through the ENV hash.

ENV['FOO']
ENV.fetch('FOO') # will raise a KeyError if it is not set instead of just returning nil

Rails 5.2 and up have secure credentials that can be used instead. It stores your credentials in an encrypted YAML file that can be checked into source control.

How do I refactor this?

One way to refactor this would be to use delegation instead of bunch of largely static methods:

require 'forwardable'

class MyClient
  extend Forwardable
  TOKEN = ENV.fetch('IEX_API_TOKEN')
  ENDPOINT = ENV.fetch('IEX_API_ENDPOINT', 'https://sandbox.iexapis.com/v1')

  def_delegators :@client, :company, :quote, :key_stats

  def initialize(publishable_token: TOKEN, endpoint: ENDPOINT, client: nil)
    # This is know as constructor injection and makes it easy to mock out
    # the dependency in tests
    @client = client || IEX::Api::Client.new(publishable_token: TOKEN, endpoint: ENDPOINT)
  end

  def stock_price(ticker)
    company_name = company(ticker).company_name
    price = quote(ticker.upcase).latest_price
    puts "#{company_name}: #{price}"
  end

  def week_52_high(ticker)
    puts "52-week high: #{key_stats(ticker).week_52_high}"
  end

  def week_52_low(ticker)
    puts "52-week low: #{key_stats(ticker).week_52_low}"
  end
end

@client = MyClient.new
@client.week_52_low(ticker)


问:
Application crash when calling method 'FirebaseApp.configure()' in a real device
Recently, I decided to run the application on a real device and received a crash application and, looking for the reason, I found that it appears after the FirebaseApp.configure() method.

The application does not crash when launched in the simulator.

Crash:

```<code>dyld`__abort_with_payload:
    0x101b0b2a4 <+0>:  mov    x16, #0x209
    0x101b0b2a8 <+4>:  svc    #0x80
->  0x101b0b2ac <+8>:  b.lo   0x101b0b2c8               ; <+36>
    0x101b0b2b0 <+12>: stp    x29, x30, [sp, #-0x10]!
    0x101b0b2b4 <+16>: mov    x29, sp
    0x101b0b2b8 <+20>: bl     0x101b097d8               ; cerror_nocancel
    0x101b0b2bc <+24>: mov    sp, x29
    0x101b0b2c0 <+28>: ldp    x29, x30, [sp], #0x10
    0x101b0b2c4 <+32>: ret
    0x101b0b2c8 <+36>: ret
</code>```

With this backtrace:

```<code>* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
  * frame #0: 0x0000000101b0b2ac dyld`__abort_with_payload + 8
    frame #1: 0x0000000101b12914 dyld`abort_with_payload_wrapper_internal + 104
    frame #2: 0x0000000101b12948 dyld`abort_with_payload + 16
    frame #3: 0x0000000101b0f77c dyld`dyld::halt(char const*) + 380
    frame #4: 0x0000000101ac0778 dyld`dyld::fastBindLazySymbol(ImageLoader**, unsigned long) + 176
    frame #5: 0x00000001b207963c libdyld.dylib`_dyld_fast_stub_entry(void*, long) + 80
    frame #6: 0x00000001b2077b80 libdyld.dylib`dyld_stub_binder + 60
    frame #7: 0x0000000100b88258 CheeseApp`__44+[UIViewController(APMScreenClassName) load]_block_invoke + 144
    frame #8: 0x000000010204327c libdispatch.dylib`_dispatch_client_callout + 20
    frame #9: 0x0000000102044c88 libdispatch.dylib`_dispatch_once_callout + 132
    frame #10: 0x0000000100b881c4 CheeseApp`+[UIViewController(APMScreenClassName) load] + 76
    frame #11: 0x00000001b1fa1500 libobjc.A.dylib`load_images + 1176
    frame #12: 0x0000000101abe19c dyld`dyld::notifySingle(dyld_image_states, ImageLoader const*, ImageLoader::InitializerTimingList*) + 480
    frame #13: 0x0000000101ace444 dyld`ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) + 556
    frame #14: 0x0000000101acd094 dyld`ImageLoader::processInitializers(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) + 192
    frame #15: 0x0000000101acd160 dyld`ImageLoader::runInitializers(ImageLoader::LinkContext const&, ImageLoader::InitializerTimingList&) + 96
    frame #16: 0x0000000101abe4f8 dyld`dyld::initializeMainExecutable() + 220
    frame #17: 0x0000000101ac3038 dyld`dyld::_main(macho_header const*, unsigned long, int, char const**, char const**, char const**, unsigned long*) + 4668
    frame #18: 0x0000000101abd22c dyld`dyldbootstrap::start(dyld3::MachOLoaded const*, int, char const**, dyld3::MachOLoaded const*, unsigned long*) + 432
    frame #19: 0x0000000101abd038 dyld`_dyld_start + 56
</code>```

AppDelegate:

```<code>import UIKit
import Firebase

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        FirebaseApp.configure()
        return true
    }

    // MARK: UISceneSession Lifecycle

    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        // Called when a new scene session is being created.
        // Use this method to select a configuration to create the new scene with.
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    }

    func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
        // Called when the user discards a scene session.
        // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
        // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
    }
}
</code>```

What I tried:

I updated the GoogleService-Info.plist file in the root directory

I updated all libraries in pod file

I tried to solve the problem by disabling the Address Sanitizer in scheme

I tried to add .plist file via "Add Files to..."

I tried to run the method like this:

```<code>    override init() {
        FirebaseApp.configure()
    }
</code>```

I updated library in 'Linked Binary With Libraries'

But nothing helped.

答: This is probably due to library image not loaded in release build. See if library is checked in 'Linked Binary With Libraries' section in your 'Build Phases'.</p>

Body:
Recently, I decided to run the application on a real device and received a crash application and, looking for the reason, I found that it appears after the FirebaseApp.configure() method.

The application does not crash when launched in the simulator.

Crash:

dyld`__abort_with_payload:
    0x101b0b2a4 <+0>:  mov    x16, #0x209
    0x101b0b2a8 <+4>:  svc    #0x80
->  0x101b0b2ac <+8>:  b.lo   0x101b0b2c8               ; <+36>
    0x101b0b2b0 <+12>: stp    x29, x30, [sp, #-0x10]!
    0x101b0b2b4 <+16>: mov    x29, sp
    0x101b0b2b8 <+20>: bl     0x101b097d8               ; cerror_nocancel
    0x101b0b2bc <+24>: mov    sp, x29
    0x101b0b2c0 <+28>: ldp    x29, x30, [sp], #0x10
    0x101b0b2c4 <+32>: ret
    0x101b0b2c8 <+36>: ret

With this backtrace:

* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
  * frame #0: 0x0000000101b0b2ac dyld`__abort_with_payload + 8
    frame #1: 0x0000000101b12914 dyld`abort_with_payload_wrapper_internal + 104
    frame #2: 0x0000000101b12948 dyld`abort_with_payload + 16
    frame #3: 0x0000000101b0f77c dyld`dyld::halt(char const*) + 380
    frame #4: 0x0000000101ac0778 dyld`dyld::fastBindLazySymbol(ImageLoader**, unsigned long) + 176
    frame #5: 0x00000001b207963c libdyld.dylib`_dyld_fast_stub_entry(void*, long) + 80
    frame #6: 0x00000001b2077b80 libdyld.dylib`dyld_stub_binder + 60
    frame #7: 0x0000000100b88258 CheeseApp`__44+[UIViewController(APMScreenClassName) load]_block_invoke + 144
    frame #8: 0x000000010204327c libdispatch.dylib`_dispatch_client_callout + 20
    frame #9: 0x0000000102044c88 libdispatch.dylib`_dispatch_once_callout + 132
    frame #10: 0x0000000100b881c4 CheeseApp`+[UIViewController(APMScreenClassName) load] + 76
    frame #11: 0x00000001b1fa1500 libobjc.A.dylib`load_images + 1176
    frame #12: 0x0000000101abe19c dyld`dyld::notifySingle(dyld_image_states, ImageLoader const*, ImageLoader::InitializerTimingList*) + 480
    frame #13: 0x0000000101ace444 dyld`ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) + 556
    frame #14: 0x0000000101acd094 dyld`ImageLoader::processInitializers(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) + 192
    frame #15: 0x0000000101acd160 dyld`ImageLoader::runInitializers(ImageLoader::LinkContext const&, ImageLoader::InitializerTimingList&) + 96
    frame #16: 0x0000000101abe4f8 dyld`dyld::initializeMainExecutable() + 220
    frame #17: 0x0000000101ac3038 dyld`dyld::_main(macho_header const*, unsigned long, int, char const**, char const**, char const**, unsigned long*) + 4668
    frame #18: 0x0000000101abd22c dyld`dyldbootstrap::start(dyld3::MachOLoaded const*, int, char const**, dyld3::MachOLoaded const*, unsigned long*) + 432
    frame #19: 0x0000000101abd038 dyld`_dyld_start + 56

AppDelegate:

import UIKit
import Firebase

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        FirebaseApp.configure()
        return true
    }

    // MARK: UISceneSession Lifecycle

    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        // Called when a new scene session is being created.
        // Use this method to select a configuration to create the new scene with.
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    }

    func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
        // Called when the user discards a scene session.
        // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
        // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
    }
}

What I tried:

I updated the GoogleService-Info.plist file in the root directory

I updated all libraries in pod file

I tried to solve the problem by disabling the Address Sanitizer in scheme

I tried to add .plist file via "Add Files to..."

I tried to run the method like this:

    override init() {
        FirebaseApp.configure()
    }

I updated library in 'Linked Binary With Libraries'

But nothing helped.


问:
How does String.toLowerCase() actually work? How can one create that functionality manually?
To set a String to lowercase, we just need to call the function toLowerCase() on it. But, for a language I am working in right now, there is no such function, so I would need to create one myself. How is Javascript able to achieve that manually?

答:
For ASCII it's just a simple "take the letter's character code, add 32, and you're done because that's how the numerical codes in ASCII were arranged", but you're asking about JavaScript toLowerCase(), which is a Unicode function: things are complicated.

In unicode land, there aren't just single "uppercase -> lowercase" mappings, there are also "this uppercase character is actually a variant of this other uppercase character" letters, as well as "this uppercase-looking character is actually a ligature and needs to be decomposed into multiple lowercase characters", as well as "this uppercase character has no lowercase equivalent" so in reality a proper toLowerCase function has to examine the Unicode case data to determine how to transform each character in a string to its lowercase equivalent, if one exists.

For example, for Latin characters (often called "ascii" characters, but that's not really true: ASCII is a set of exactly 128 codes, quite a lot of which are not printable) we see data like this:

```<code>...
0041;LATIN CAPITAL LETTER A;Lu;0;L;;;;;N;;;;0061;
...
</code>```

So we see that A, with hex code 0x41, has a lowercase equivalent at code 0x61:

```<code>...
0061;LATIN SMALL LETTER A;Ll;0;L;;;;;N;;;0041;;0041
...
</code>```

So for this set of codes, the rule is:

```<code>if (0x41 <= codepoint <= 0x5A) newcodepoint = codepoint + 0x20
</code>```

However, moving only slightly down the list we see:

```<code>...
012A;LATIN CAPITAL LETTER I WITH MACRON;Lu;0;L;0049 0304;;;;N;LATIN CAPITAL LETTER I MACRON;;;012B;
012B;LATIN SMALL LETTER I WITH MACRON;Ll;0;L;0069 0304;;;;N;LATIN SMALL LETTER I MACRON;;012A;;012A
...
</code>```

Here, the lowercase and uppercase variants are right next to each other. Adding or subtracting 32 is going to be very wrong indeed. Instead, we need to use the rule

```<code>if (0x0100 <= codepoint <= 0x012E) newcodepoint = codepoint + 1
</code>```

So a real toLowerCase is a three stage function:

Find the "mapping set" the character you're looking at is even in, and then

apply that set's rule for mapping between uppercase and lowercase, noting that even though this set exists, it might only map one way, so

if no mapping could be found, follow the official Unicode recommendations on what to do.

Also, note that in step 1 we might have to do more work than you'd think, because not every language allows every letter to be blindly mapped to a single uppercase or lowercase: depending on where in the word the letter is, there might be different uppercase or lowercase equivalents. Just to make things even more fun.

Text transformations are hard, which is why you almost never try to implement your own version: this is one of those subjects that seems stupidly simple at first glance, but when you actually sit down and research it a little, it turns out it's crazy difficult and you really need an entire team of people to write just one function, just so that every edge case is covered and there are no bugs that slipped in because you happened to miss a small rule about some rarely used character.

So to answer your question about how you'd go about implementing this for the language you're working with: you don't. Find a string library that supports your language, and file issues with the browsers in which toLowerCase() doesn't work correctly for your example, because those are bugs that need to be fixed in their implementations.

Body:
For ASCII it's just a simple "take the letter's character code, add 32, and you're done because that's how the numerical codes in ASCII were arranged", but you're asking about JavaScript toLowerCase(), which is a Unicode function: things are complicated.

In unicode land, there aren't just single "uppercase -> lowercase" mappings, there are also "this uppercase character is actually a variant of this other uppercase character" letters, as well as "this uppercase-looking character is actually a ligature and needs to be decomposed into multiple lowercase characters", as well as "this uppercase character has no lowercase equivalent" so in reality a proper toLowerCase function has to examine the Unicode case data to determine how to transform each character in a string to its lowercase equivalent, if one exists.

For example, for Latin characters (often called "ascii" characters, but that's not really true: ASCII is a set of exactly 128 codes, quite a lot of which are not printable) we see data like this:

...
0041;LATIN CAPITAL LETTER A;Lu;0;L;;;;;N;;;;0061;
...

So we see that A, with hex code 0x41, has a lowercase equivalent at code 0x61:

...
0061;LATIN SMALL LETTER A;Ll;0;L;;;;;N;;;0041;;0041
...

So for this set of codes, the rule is:

if (0x41 <= codepoint <= 0x5A) newcodepoint = codepoint + 0x20

However, moving only slightly down the list we see:

...
012A;LATIN CAPITAL LETTER I WITH MACRON;Lu;0;L;0049 0304;;;;N;LATIN CAPITAL LETTER I MACRON;;;012B;
012B;LATIN SMALL LETTER I WITH MACRON;Ll;0;L;0069 0304;;;;N;LATIN SMALL LETTER I MACRON;;012A;;012A
...

Here, the lowercase and uppercase variants are right next to each other. Adding or subtracting 32 is going to be very wrong indeed. Instead, we need to use the rule

if (0x0100 <= codepoint <= 0x012E) newcodepoint = codepoint + 1

So a real toLowerCase is a three stage function:

Find the "mapping set" the character you're looking at is even in, and then

apply that set's rule for mapping between uppercase and lowercase, noting that even though this set exists, it might only map one way, so

if no mapping could be found, follow the official Unicode recommendations on what to do.

Also, note that in step 1 we might have to do more work than you'd think, because not every language allows every letter to be blindly mapped to a single uppercase or lowercase: depending on where in the word the letter is, there might be different uppercase or lowercase equivalents. Just to make things even more fun.

Text transformations are hard, which is why you almost never try to implement your own version: this is one of those subjects that seems stupidly simple at first glance, but when you actually sit down and research it a little, it turns out it's crazy difficult and you really need an entire team of people to write just one function, just so that every edge case is covered and there are no bugs that slipped in because you happened to miss a small rule about some rarely used character.

So to answer your question about how you'd go about implementing this for the language you're working with: you don't. Find a string library that supports your language, and file issues with the browsers in which toLowerCase() doesn't work correctly for your example, because those are bugs that need to be fixed in their implementations.


问:
How do you declare a value constrained type?
Ada

```<code>type Year_type is range 1800 .. 2100;
</code>```

Raku

```<code>subset Natural of Int where * ≥ 0;
</code>```

Kavorka

```<code>Int $even where { $_ % 2 == 0 }
</code>```

TS

```<code>type Natural = BigInteger /* hypothetical → */ where (n) => { return n >= 0 };
</code>```

答:
As far as I know, here isn't such a type of constraint or Range and one solution by be creating a specific class implementing those constrains.

In addition to this the union types may help you with smaller ranges:

```<code>type EvenDigits  = 0 | 2 | 4 | 6 | 8;
</code>```

Body:
Ada

type Year_type is range 1800 .. 2100;

Raku

subset Natural of Int where * ≥ 0;

Kavorka

Int $even where { $_ % 2 == 0 }

TS

type Natural = BigInteger /* hypothetical → */ where (n) => { return n >= 0 };

Body:
As far as I know, here isn't such a type of constraint or Range and one solution by be creating a specific class implementing those constrains.

In addition to this the union types may help you with smaller ranges:

type EvenDigits  = 0 | 2 | 4 | 6 | 8;


问:
Navbar items are not clickable and nav items at right side are not getting aligned properly

Two navbar items i.e. About us and Contact us are not
  clickable. How to make these navbar items clickable?

and how to align one of the navbar item properly i.e. Login which is currently
  positioned at rightmost part of the navbar.This login item has dropdown menu which only gets partially displayed because it is situated in rightmost part.

html {
  height: 100%;
}

.navbar-light .navbar-brand {
  color: black;
}

body {
  background: linear-gradient(rgba(255, 255, 255, .5), rgba(255, 255, 255, .5)), url(https://images.unsplash.com/photo-1486312338219-ce68d2c6f44d?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=752&q=80) no-repeat center center fixed;
  background-size: cover;
  background-position: center;
  font-family: catamaran;
}

.center {
  text-align: center;
  margin: 0 auto;
  padding: 5%;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}

.navbar {
  height: 45px;
}

h1,
p {
  color: black;
}

h2>span {
  color: black;
}

@media (max-width:768px) {
  h1 {
    background-color: #449d44;
  }
  h2 {
    background-color: #449d44;
  }
}

@media (min-width:768px) {
  h1 {
    background-color: skyblue;
  }
}

.nav-item active {
  text-align: left;
}

#Login {
  min-width: 250px;
  background-color: rgba(255, 255, 255, 0.7);
  padding: 14px 14px 0;
}

}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">

  <link rel="stylesheet" href="css/technical_landing.css">
  <link href="https://fonts.googleapis.com/css?family=Catamaran&display=swap" rel="stylesheet">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/all.min.css">

  <title>Minimum Bootstrap HTML Skeleton</title>

  <!--  -->

  <style>

  </style>

</head>

<body>

  <nav class="navbar navbar-expand-lg navbar-light bg-light">
    Technical lab
    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>

    <div class="  collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav mr-auto">

        <li class="nav-item active ">
          Home <span class="sr-only">(current)</span>
        </li>

        <li class="nav-item ">
          About us
        </li>

        <li class="nav-item ">
          Contact us
        </li>

      </ul>

      <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>

      <div class="collapse navbar-collapse" id="navbarSupportedContent">
        <ul class="navbar-nav ml-auto">
          <li class="nav-item active">
            Sign Up <span class="sr-only">(current)</span></li>

          <li class="dropdown">
             Log in <span class="caret"></span>

            <ul id="Login" class="dropdown-menu">
              <li>
                <div class="row">
                  <div class="col-md-12">
                    Login via:
                    <div class="social-button">
                      <i class="fa fa-facebook"></i>Facebook
                      <i class="fa fa-twitter"></i>Twitter
                    </div>
                  </div>
                </div>
              </li>
            </ul>

          </li>

        </ul>

      </div>
  </nav>
  </div>
  </nav>

  <div class="container center">
    <div class="row">
      <div class="col-md-12">
        <h2>
          <span class="fa-stack fa-lg">
                     <i class="far fa-square fa-stack-2x"></i>
                     <i class="fab fa-twitter-square fa-stack-1x"></i>
                 </span>
        </h2>
        <h1>Technical lab is coming soon.</h1>
        <p>Waiting is not easy but just wait this time</p>
        <button class="btn btn-success btn-lg">
             <i class="fas fa-spinner"></i>
             <br>Click me</button>

      </div>
    </div>
  </div>

  <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>

  <script>
  </script>

</body>

</html></code>```

答:
Add to your CSS:

.navbar { z-index: 1;}

.navbar-nav {align-items: center;}

#Login {right: 0; position: absolute; left: unset;}

Body:
Two navbar items i.e. About us and Contact us are not
  clickable. How to make these navbar items clickable?

and how to align one of the navbar item properly i.e. Login which is currently
  positioned at rightmost part of the navbar.This login item has dropdown menu which only gets partially displayed because it is situated in rightmost part.

html {
  height: 100%;
}

.navbar-light .navbar-brand {
  color: black;
}

body {
  background: linear-gradient(rgba(255, 255, 255, .5), rgba(255, 255, 255, .5)), url(https://images.unsplash.com/photo-1486312338219-ce68d2c6f44d?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=752&q=80) no-repeat center center fixed;
  background-size: cover;
  background-position: center;
  font-family: catamaran;
}

.center {
  text-align: center;
  margin: 0 auto;
  padding: 5%;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}

.navbar {
  height: 45px;
}

h1,
p {
  color: black;
}

h2>span {
  color: black;
}

@media (max-width:768px) {
  h1 {
    background-color: #449d44;
  }
  h2 {
    background-color: #449d44;
  }
}

@media (min-width:768px) {
  h1 {
    background-color: skyblue;
  }
}

.nav-item active {
  text-align: left;
}

#Login {
  min-width: 250px;
  background-color: rgba(255, 255, 255, 0.7);
  padding: 14px 14px 0;
}

}

<!DOCTYPE html>

  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">

  <link rel="stylesheet" href="css/technical_landing.css">
  <link href="https://fonts.googleapis.com/css?family=Catamaran&display=swap" rel="stylesheet">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/all.min.css">

  <title>Minimum Bootstrap HTML Skeleton</title>

    Technical lab
    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">

      </button>

          Home (current)

          About us

          Contact us

      <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">

      </button>

            Sign Up (current)

             Log in

                    Login via:

                      Facebook
                      Twitter

Technical lab is coming soon.

Waiting is not easy but just wait this time

        <button class="btn btn-success btn-lg">

Click me</button>


问:
How to show exactly 4 numbers after decimal point without rounding in Python?
I want to calculate square root of numbers and print them with exactly 4 numbers after decimal point without rounding.
This code rounds the numbers

```<code>num="%.4f" % num
</code>```

and this one doesn't show 1.0000 or numbers like this.

```<code>num=math.floor(num * 10000)/10000
</code>```

答:
You can convert them into string. Here's a way -

num = str(0.5532523).split('.')
ans = '%s.%s' % (num[0], num[1][:4])
print(ans)
```

Body:
I want to calculate square root of numbers and print them with exactly 4 numbers after decimal point without rounding.
This code rounds the numbers

num="%.4f" % num

and this one doesn't show 1.0000 or numbers like this.

num=math.floor(num * 10000)/10000


问:
How to delete object/row with jquery (post form)
I have a model posts where users can edit and delete their own posts. My index page is a table with a few columns for each post. One of them holds a form for the delete button. Is there any examples on how you jquery submit a post/delete form with rails? I need to pass the status back to the user. Eg. posts deleted, access denied etc and remove the row if successfull.

Best regards.
Asbjørn Morell.

答:
If the action is successful the response will be a successful one (i.e. 200 OK). In your jQuery you can add an error function if the request encounters an error:

```<code>error: function() {
  // the item has not been deleted
  // and we encountered an error
}
</code>```

Then in your Controller if you want to explicitly return your own error:

```<code>render :text => 'Could not compute!', :status => :unprocessable_entity
</code>```

Or any other error. Hope this helps.

OwnerDisplayName: atmorell

ContentLicense: CC BY-SA 2.5

Body:
If the action is successful the response will be a successful one (i.e. 200 OK). In your jQuery you can add an error function if the request encounters an error:

error: function() {
  // the item has not been deleted
  // and we encountered an error
}

Then in your Controller if you want to explicitly return your own error:

render :text => 'Could not compute!', :status => :unprocessable_entity

Or any other error. Hope this helps.

OwnerDisplayName: marktucks


问:
How to resize an image without loading into memory?
I'd like to check the dimensions of an image, and then size it down if the width exceeds a given threshold.  When I load a 6MB JPEG image with ImageIO.read(), the BufferedImage allocates about 45MB of heap space.  Is there a way to do a passthrough image resize without loading all the data into memory?  I tried passing ImageIO.read() a File object, thinking it would stream the data from disk, but it doesn't help.</p>

答:
Check out im4java and JMagick.  Both use an extremely efficient external tool called ImageMagick for image manipulation.  Im4Java calls the command-line app (does work in separate process), and JMagick calls it within the same process via JNI.

If I'm doing simple image manipulation (resizing, scaling, rotating, etc), I'd much rather let ImageMagick do it for me.  It'll be faster, more reliable, and consume less memory than anything you'd implement in a similar amount of time.

Hope this helps!

ContentLicense: CC BY-SA 3.0


问:
Get the first child from Firebase without knowing the name
I want to get the children of "games" but I have to know the names of the children.

```<code>public void getdata()
{
    FirebaseApp.DefaultInstance.SetEditorDatabaseUrl("url...");
    FirebaseDatabase.DefaultInstance.GetReference("games").GetValueAsync().ContinueWith(task => {
        if (task.IsFaulted)
        {
            Debug.Log(task.Exception);
        }
        else if (task.IsCompleted)
        {
            DataSnapshot snapshot = task.Result;
            //Get the children of "games" and Debug.log them
            snapshot.Child("path"); // Requires the path. What if I don't know the path ?
        }
    });
}
</code>```

Doesen't there exist something like:

```<code>snapshot.Child(0);
snapshot.Child(1);
</code>```

答:
Firebase doesn't offer an array-like view of your data, and there is no default ordering of the children. The order you're seeing in the console is just an alphabetical sort on the name of the children.

You will need to either know the names of the children, or be able to use an ordered type query where the data in the children themselves are used to determine which one comes first.  I suggest reading the documentation to learn how to query by ordering.  You will need to define some data in your children to figure out which one should come first.  Then, to get only the first child, you can limit the results to just one.

Body:
I want to get the children of "games" but I have to know the names of the children.

public void getdata()
{
    FirebaseApp.DefaultInstance.SetEditorDatabaseUrl("url...");
    FirebaseDatabase.DefaultInstance.GetReference("games").GetValueAsync().ContinueWith(task => {
        if (task.IsFaulted)
        {
            Debug.Log(task.Exception);
        }
        else if (task.IsCompleted)
        {
            DataSnapshot snapshot = task.Result;
            //Get the children of "games" and Debug.log them
            snapshot.Child("path"); // Requires the path. What if I don't know the path ?
        }
    });
}

Doesen't there exist something like:

snapshot.Child(0);
snapshot.Child(1);


问:
regex in C language to pull chrome version out of user agent
I am trying to write a C code with regex.h library  that can find out a Chrome version from user agent. I am trying below

```<code>regex_t re;
regmatch_t pm;

if(regcomp(&re, "Chrom[^ \\/]+\\/(\\d+)[\\.\\d]* ", 0) != 0) {
    cout << "C - Invalid Regex\n";
    return;
} else {
    cout << "C - valid Regex\n";
}

if ( regexec(&re, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.3987.66 Safari/537.36", 1, &pm, 0) == 0 ) {
    cout << "Match Found !!" << "start location: " << pm.rm_so << "end location: " << pm.rm_eo << "\n";
} else {
    cout << "Match Not Found\n";
}
regfree(&re);
</code>```

but this does not work and it prints "Match Not Found". What am i missing ?

答:
Try this:

```<code>regcomp(&re, "Chrome\\/[0-9]+[.[0-9]+]*", REG_EXTENDED)
</code>```

You can get more info about regex.h here:
https://pubs.opengroup.org/onlinepubs/7908799/xsh/regex.h.html

Body:
I am trying to write a C code with regex.h library  that can find out a Chrome version from user agent. I am trying below

regex_t re;
regmatch_t pm;

if(regcomp(&re, "Chrom[^ \\/]+\\/(\\d+)[\\.\\d]* ", 0) != 0) {
    cout << "C - Invalid Regex\n";
    return;
} else {
    cout << "C - valid Regex\n";
}

if ( regexec(&re, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.3987.66 Safari/537.36", 1, &pm, 0) == 0 ) {
    cout << "Match Found !!" << "start location: " << pm.rm_so << "end location: " << pm.rm_eo << "\n";
} else {
    cout << "Match Not Found\n";
}
regfree(&re);

but this does not work and it prints "Match Not Found". What am i missing ?

Body:
Try this:

regcomp(&re, "Chrome\\/[0-9]+[.[0-9]+]*", REG_EXTENDED)

You can get more info about regex.h here:
https://pubs.opengroup.org/onlinepubs/7908799/xsh/regex.h.html


问:
Load a big file at pandas and filter columns before loadings
I´m trying to load a csv at pandas, but my computer keeps freezing. The csv has more than 20k columns and 500k rows, but I only need a few to them

```<code>df = pd.read_csv('e:/teste/teste/file.txt', sep="|", header=None, encoding="latin1", error_bad_lines=False, engine= 'python', dtype='unicode', usecols = [4,6,7,8,9,10,11,12,13,14,15,16,21,22,23,24,25,26,56,93])
</code>```

The computer hangs if I load just a few of the columns.
Anyone knows how can I fix it?

答:
When you want to read a big file the best way to do it is with chunks

```<code>mylist = []
for chunk in pd.read_csv(file, chunksize=Number):
    mylist.append(chunk)
df = pd.concat(mylist, axis= 0)
</code>```

Put the chunk in an array and later concatenate all chunks. Is more memory efficent than concatenate in every iteration.

And for the columns in the docs of pandas read_csv there's a usecols parameter, I hope it helps

Body:
I´m trying to load a csv at pandas, but my computer keeps freezing. The csv has more than 20k columns and 500k rows, but I only need a few to them

df = pd.read_csv('e:/teste/teste/file.txt', sep="|", header=None, encoding="latin1", error_bad_lines=False, engine= 'python', dtype='unicode', usecols = [4,6,7,8,9,10,11,12,13,14,15,16,21,22,23,24,25,26,56,93])

The computer hangs if I load just a few of the columns.
Anyone knows how can I fix it?

Body:
When you want to read a big file the best way to do it is with chunks

mylist = []
for chunk in pd.read_csv(file, chunksize=Number):
    mylist.append(chunk)
df = pd.concat(mylist, axis= 0)

Put the chunk in an array and later concatenate all chunks. Is more memory efficent than concatenate in every iteration.

And for the columns in the docs of pandas read_csv there's a usecols parameter, I hope it helps


问:
how to select specific json data and store it into an array in Vue Js?
I am facing issue to store category SINGLES related data into an array and then use this array to display show data.Basically, I just want to store data that is only belong to category "SINGLES" from json file that I named it "data.json" into an array.Can anyone help me please. I would really appreciate that.
Index.html

```<code><div id="app">
<div class="col-lg-4 col-sm-6" v-for="model in jsonSingleData">
 <div class="beeton-models-box">
<div class="image-holder">
</div>
<div class="text-box">
<h3>{{model.title}}</h3>
<p>{{model.bedrooms}}</p>

</div>
</div>
</div>
</div>

script.js

var vm = new Vue({

el:'#app',
data:{

    jsonSingleData:[]

},
created:function(){
   this.fetchDataAll();

},

methods:{

fetchDataAll: function(){

    var url="data.json";
    axios.get(url)
    .then(function(res){

     res.data.models.forEach(single=>{

            if(single.category=='SINGLES')
            {

                vm.jsonSingleData=single;
                console.log(single);

            }

        });

    });

}
</code>```

The below is my json file.
data.json

```<code>{
    "models": [
      {
        "title": "IRIS",
        "project": "ABC",
        "category": "SINGLES",
        "bedrooms": 3

      },
      {
        "title": "LILAC",
        "project": "ABC",
        "category": "DOUBLE",
        "bedrooms": 4

      },
      {
        "title": "ASTER",
        "project": "ABC",
        "category": "SINGLES",
        "bedrooms": 4

      }
    ]
  }
</code>```

答:
Looks like your method is missing some points. Also, you are missing a } at the end.

Try this:

```<code>fetchDataAll: function(){
    var vm = this;
    var url="data.json";
    axios.get(url)
    .then(function(res){

     res.data.models.forEach((single)=>{

            if(single.category=='SINGLES')
            {

                vm.jsonSingleData.push(single);
                console.log(single);

            }

        });

    });

}
</code>```

Body:
I am facing issue to store category SINGLES related data into an array and then use this array to display show data.Basically, I just want to store data that is only belong to category "SINGLES" from json file that I named it "data.json" into an array.Can anyone help me please. I would really appreciate that.
Index.html

{{model.title}}

{{model.bedrooms}}

script.js

var vm = new Vue({

el:'#app',
data:{

    jsonSingleData:[]

},
created:function(){
   this.fetchDataAll();

},

methods:{

fetchDataAll: function(){

    var url="data.json";
    axios.get(url)
    .then(function(res){

     res.data.models.forEach(single=>{

            if(single.category=='SINGLES')
            {

                vm.jsonSingleData=single;
                console.log(single);

            }

        });

    });

}

The below is my json file.
data.json

{
    "models": [
      {
        "title": "IRIS",
        "project": "ABC",
        "category": "SINGLES",
        "bedrooms": 3

      },
      {
        "title": "LILAC",
        "project": "ABC",
        "category": "DOUBLE",
        "bedrooms": 4

      },
      {
        "title": "ASTER",
        "project": "ABC",
        "category": "SINGLES",
        "bedrooms": 4

      }
    ]
  }

Body:
Looks like your method is missing some points. Also, you are missing a } at the end.

Try this:

fetchDataAll: function(){
    var vm = this;
    var url="data.json";
    axios.get(url)
    .then(function(res){

     res.data.models.forEach((single)=>{

            if(single.category=='SINGLES')
            {

                vm.jsonSingleData.push(single);
                console.log(single);

            }

        });

    });

}


问:
Multilanguage PHP website URL filename change
I currently have a multilanguage PHP site on which everything works fine. However, the "file name" does not change when "switching the language."

The URLs are like this:

www.site.com/br/article.pt.php

www.site.com/en/article.en.php

I want them to be:

www.site.com/br/meuartigo.pt.php

www.site.com/en/article.en.php

How can I do this? I could just do 301 redirects from

www.site.com/br/article.pt.php

to

www.site.com/br/meuartigo.pt.php

but I don't think that's the best way.

答:
Your goal should be

```<code>www.site.com/br/meuartigo
www.site.com/en/article
</code>```

That's the common format for 'SEO friendly urls'.

You can get a way to do it in the answer to this question:
Simulate file structure with PHP

Body:
Your goal should be

www.site.com/br/meuartigo
www.site.com/en/article

That's the common format for 'SEO friendly urls'.

You can get a way to do it in the answer to this question:
Simulate file structure with PHP


问:
REST API ROUTE PATHS - best practice for authenticated resource?
I have an API built with Laravel that works with authentication tokens (the passport package). It is unclear to me what should be the best practice for resources that are accessed within an authenticated session.

Let me explain.

Let's say I would like to see the orders of a user as an administrator, I visit: /v1/users/5/orders and all orders get listed for user with ID 5.

But now the user with ID 5 is authenticated. What should the URL be to access his own orders resource?

Would that be: /v1/users/5/orders (and check if it's either an admin or the session belongs to the user with ID of 5)

OR /v1/my/orders

OR /v1/my-orders

OR /v1/orders (and use session ID of user 5, - OR list all results when admin)

It just gets confusing when on the same URL the orders can be listed because an admin wants to access it. Or it is actually the session user that wants to see them.

答:
I would suggest using /v1/orders, that will display a collection of orders based on privileges:
- all orders in case of an admin session
- orders belonging to the authenticated user, in case of a less privileged user.

Adding a prefix like /my/orders or my-orders does not bring any value.

For the sub-collections I would keep the route /v1/users/5/orders that will allow admin to access user orders.

This is a pretty good tutorial that explains API resource naming: https://restfulapi.net/resource-naming/


问:
CodeIgniter 4 problem installing with composer
I'm having problems trying to install CodeIgniter 4 via Composer, on a local server (xampp)

The code that throws me is the following:

```<code>    PS C:\Users\PuercoRico> cd D:\xampp\htdocs
PS D:\xampp\htdocs> composer create-project codeigniter4/appstarter ci4 -s rc
Installing codeigniter4/appstarter (4.0.0-rc.4)
  - Installing codeigniter4/appstarter (4.0.0-rc.4): Loading from cache
Created project in ci4
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - codeigniter4/framework v4.0.0-rc.3 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - codeigniter4/framework v4.0.0-rc.2.1 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - codeigniter4/framework v4.0.0-rc.2 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - codeigniter4/framework v4.0.0-rc.1 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - codeigniter4/framework 4.0.0-rc.4 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - Installation request for codeigniter4/framework ^4@rc -> satisfiable by codeigniter4/framework[4.0.0-rc.4, v4.0.0-rc.1, v4.0.0-rc.2, v4.0.0-rc.2.1, v4.0.0-rc.3].

  To enable extensions, verify that they are enabled in your .ini files:
    - D:\xampp\php\php.ini
  You can also run `php --ini` inside terminal to see which files are used by PHP in CLI mode.
</code>```

The version of php that I am using is 7.4.1

Any idea what the error may be or how I can fix it.

答:
Your PHP is missing intl extension. It is useful for formatting currency, number and date/time as well as UCA-conformant collations, for message formatting and normalizing text..etc.

Check out Codeignitor 4 [Documentation][1]:

Follow the steps to install it in XAMPP -

Open [xampp_folder_path]/php/php.ini to edit.

Search for ;extension=intl and remove the ;.

Save the php.ini file and restart Apache.

Body:
I'm having problems trying to install CodeIgniter 4 via Composer, on a local server (xampp)

The code that throws me is the following:

    PS C:\Users\PuercoRico> cd D:\xampp\htdocs
PS D:\xampp\htdocs> composer create-project codeigniter4/appstarter ci4 -s rc
Installing codeigniter4/appstarter (4.0.0-rc.4)
  - Installing codeigniter4/appstarter (4.0.0-rc.4): Loading from cache
Created project in ci4
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - codeigniter4/framework v4.0.0-rc.3 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - codeigniter4/framework v4.0.0-rc.2.1 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - codeigniter4/framework v4.0.0-rc.2 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - codeigniter4/framework v4.0.0-rc.1 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - codeigniter4/framework 4.0.0-rc.4 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - Installation request for codeigniter4/framework ^4@rc -> satisfiable by codeigniter4/framework[4.0.0-rc.4, v4.0.0-rc.1, v4.0.0-rc.2, v4.0.0-rc.2.1, v4.0.0-rc.3].

  To enable extensions, verify that they are enabled in your .ini files:
    - D:\xampp\php\php.ini
  You can also run `php --ini` inside terminal to see which files are used by PHP in CLI mode.

The version of php that I am using is 7.4.1

Any idea what the error may be or how I can fix it.


问:
ApolloLink to Headless CMS / Cross Origin Domain (Wordpress WPGraphQL Endpoint) not Working: Apache 500 Error
Setup: I have a Gatsby project, which uses an ApolloLink to create a connection between the GraphQL endpoint of my headless CMS (Wordpress endpoint, generated through the WPGraphQL plugin) and my frontend. The fetch method uses "no-cors". My origin currently is localhost:8000, in production has to be a different domain then the backend-domain.

The problem: I have to host the frontend on Netlify, therefore front- and backend are on different domains. When I make the Apollo request to the headless CMS, the response headers return an error 500.

in gatsby-browser

const link = createHttpLink({
  uri: 'https://my-other-endpoint.com/graphql',
  credentials: 'include',
  headers: {
    'Content-Type': 'application/json',
    'Origin': 'http://localhost:8000'
  },
  fetchOptions: {
    mode: 'no-cors'
  }
});

const client = new ApolloClient({
  cache: new InMemoryCache(),
  link
});```
</div>
</div>
</p>

<p>graphql query:</p>

<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-js lang-js prettyprint-override"><code>const TEST_QUERY = gql`
  query {competenceBy(competenceId:1067){date}}
`;</code>```

the component, which should render the data:

const MyComp = (props) => {
  const { loading, data, error } = useQuery(TEST_QUERY, { errorPolicy: 'all' });

  if (loading) return
Loading Posts...
;

  if (error) {
    return (

        graphQLErrors:

        {error.graphQLErrors.map(({ message }) => (
          {message}
        ))}

        {error.message}

    )
  }

  const { page } = data;
  console.log("TCL: CompetencesPageTemplate -> page", page)

  return (
    <>
        {
          page.acf.content_competences
        }
    </>
  );

}

export default MyComp```
</div>
</div>
</p>

<p>in the .htaccess on my server: </p>

<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-js lang-js prettyprint-override"><code>Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *</code>```

答: To configure the CORS Header in your WPGraphQL request, try using the WPGraphQL-CORS plugin on your WordPress backend. It was designed for this very scenario.

Body:
Setup: I have a Gatsby project, which uses an ApolloLink to create a connection between the GraphQL endpoint of my headless CMS (Wordpress endpoint, generated through the WPGraphQL plugin) and my frontend. The fetch method uses "no-cors". My origin currently is localhost:8000, in production has to be a different domain then the backend-domain.

The problem: I have to host the frontend on Netlify, therefore front- and backend are on different domains. When I make the Apollo request to the headless CMS, the response headers return an error 500.

in gatsby-browser

const link = createHttpLink({
  uri: 'https://my-other-endpoint.com/graphql',
  credentials: 'include',
  headers: {
    'Content-Type': 'application/json',
    'Origin': 'http://localhost:8000'
  },
  fetchOptions: {
    mode: 'no-cors'
  }
});

const client = new ApolloClient({
  cache: new InMemoryCache(),
  link
});

graphql query:

const TEST_QUERY = gql`
  query {competenceBy(competenceId:1067){date}}
`;

the component, which should render the data:

const MyComp = (props) => {
  const { loading, data, error } = useQuery(TEST_QUERY, { errorPolicy: 'all' });

  if (loading) return
Loading Posts...
;

  if (error) {
    return (

        graphQLErrors:

        {error.graphQLErrors.map(({ message }) => (
          {message}
        ))}

        {error.message}

    )
  }

  const { page } = data;
  console.log("TCL: CompetencesPageTemplate -> page", page)

  return (
    <>
        {
          page.acf.content_competences
        }
    </>
  );

}

export default MyComp

in the .htaccess on my server:

Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *


问:
Does tree object type in git internals point to the blob only or to trees as well?
I've explored a lot about the 3 commit model of the git internals and in the diagram,it's shown that tree object type is pointing to the other trees as well, but when I do
git cat-file -p 'sha-hash',
It tells that tree is pointing to the blobs only.
Please refer to the screenshot attached.
Please help me with a screenshot where tree is pointing to some other tree or tell me any use case which I may be missing.

答:
I think @torek has explained it pretty well. Also, I would like to add on that this all storage is done in the form of SHA1 hashes, the blob(binary large object) stores file contents while the trees store, in maybe vague terms, the file name and subtrees inside of it.

This is a pretty good guide to the internals of Git, you might as well take a look at it.

Cheers!


问:
telegram bot with cron and PHP script
on EC2

I have a crontab like that

```<code>* * * * * /usr/bin/php /opt/bitnami/apache2/htdocs/bot.php
</code>```

The bot.php file

```<code>  1 <?php
  2
  3 exec( 'touch /opt/bitnami/apache2/htdocs/testCron.txt');
  4
  5   $botToken="xxxxxxxxxxxxx";
  6
  7   $website="https://api.telegram.org/bot".$botToken;
  8   $chatId=123456;
  9   $params=[
 10       'chat_id'=>$chatId,
 11       'text'=>'test bitnami',
 12   ];
 13   $ch = curl_init($website . '/sendMessage');
 14   curl_setopt($ch, CURLOPT_HEADER, false);
 15   curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
 16   curl_setopt($ch, CURLOPT_POST, 1);
 17   curl_setopt($ch, CURLOPT_POSTFIELDS, ($params));
 18   curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
 19   $result = curl_exec($ch);
 20
 21   if ($result === FALSE) {
 22      echo 'An error has occured: ' . curl_error($ch) . PHP_EOL;
 23   }
 24   else {
 25      echo $result;
 26   }
 27
 28   curl_close($ch);
 29
 30 ?>
</code>```

testCron.txt is created so the cronTab works.

When I open bot.php with firefox the API call works and the bot sent the message on Telegram, but the PHP script with curl doesn't work with Cron.

I put htdocs and bot.php permissions to 777 for testing and it didn't work.

Any idea?

答:
Hint: I'm adding it as an answer since my reputation (as of now) is below 50.

As of now I would need more information in order to support. There might be multiple potential issues here. Let's see if we can go down the road together.

1. Make errors visible during cron execution

In this case you could check your logs inside your cron. I would suggest to log any output into a file by the this to your cron  >> /var/log/my-cron.log 2>&1.

```<code>* * * * * /usr/bin/php /opt/bitnami/apache2/htdocs/bot.php >> /opt/bitnami/apache2/htdocs/testCron.log 2>&1
</code>```

From here on we can check if there is any execution errors, permission errors or some misconfiguration.

2. Check your error-log configuration

It might be that your errors are not displayed. Here is a good starting point for some configuration

```<code>// tells your script to report any error
error_reporting(E_ALL);

// tells your script to enable error logging and the location where it should log to
ini_set('log_errors', '1'); // tells your script to enable logging
ini_set('error_log', '/dev/stderr');

</code>```

Let's see if this is enough to get an initial idea or if we need to dig deeper.

Title: telegram bot with cron and PHP script

Body:
on EC2

I have a crontab like that

* * * * * /usr/bin/php /opt/bitnami/apache2/htdocs/bot.php

The bot.php file

  1 <?php
  2
  3 exec( 'touch /opt/bitnami/apache2/htdocs/testCron.txt');
  4
  5   $botToken="xxxxxxxxxxxxx";
  6
  7   $website="https://api.telegram.org/bot".$botToken;
  8   $chatId=123456;
  9   $params=[
 10       'chat_id'=>$chatId,
 11       'text'=>'test bitnami',
 12   ];
 13   $ch = curl_init($website . '/sendMessage');
 14   curl_setopt($ch, CURLOPT_HEADER, false);
 15   curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
 16   curl_setopt($ch, CURLOPT_POST, 1);
 17   curl_setopt($ch, CURLOPT_POSTFIELDS, ($params));
 18   curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
 19   $result = curl_exec($ch);
 20
 21   if ($result === FALSE) {
 22      echo 'An error has occured: ' . curl_error($ch) . PHP_EOL;
 23   }
 24   else {
 25      echo $result;
 26   }
 27
 28   curl_close($ch);
 29
 30 ?>

testCron.txt is created so the cronTab works.

When I open bot.php with firefox the API call works and the bot sent the message on Telegram, but the PHP script with curl doesn't work with Cron.

I put htdocs and bot.php permissions to 777 for testing and it didn't work.

Any idea?

Body:
Hint: I'm adding it as an answer since my reputation (as of now) is below 50.

As of now I would need more information in order to support. There might be multiple potential issues here. Let's see if we can go down the road together.

1. Make errors visible during cron execution

In this case you could check your logs inside your cron. I would suggest to log any output into a file by the this to your cron  >> /var/log/my-cron.log 2>&1.

* * * * * /usr/bin/php /opt/bitnami/apache2/htdocs/bot.php >> /opt/bitnami/apache2/htdocs/testCron.log 2>&1

From here on we can check if there is any execution errors, permission errors or some misconfiguration.

2. Check your error-log configuration

It might be that your errors are not displayed. Here is a good starting point for some configuration

// tells your script to report any error
error_reporting(E_ALL);

// tells your script to enable error logging and the location where it should log to
ini_set('log_errors', '1'); // tells your script to enable logging
ini_set('error_log', '/dev/stderr');

Let's see if this is enough to get an initial idea or if we need to dig deeper.


Title: Add the Values if appears consecutive to last row otherwise keep same value

Body:
I have a dataframe with two column (Time, Value) which have time data in the format HH:MM:SS and some Values against each time value. Sample data is shown below for reference:

Time        Value
09:15:00    0
09:15:30    0
09:15:31    0
09:15:32    85
09:15:33    168
09:15:34    50
09:15:34    100
09:15:35    0
09:15:35    0
09:15:36    0
09:15:37    0
09:15:37    0
09:15:38    40
09:15:39    0
09:15:39    0
09:15:39    0
09:15:40    51
09:15:40    0
09:15:41    250
09:15:42    110
09:15:43    42
09:15:44    0
09:15:45    0

I want to add the Values if appears consecutive (non zero values) to last row and need to keep same Value if Values are isolated.

Sample output as below:

Time        Value   Result
09:15:00    0       0
09:15:30    0       0
09:15:31    0       0
09:15:32    85      0
09:15:33    168     0
09:15:34    50      0
09:15:34    100     403
09:15:35    0       0
09:15:35    0       0
09:15:36    0       0
09:15:37    0       0
09:15:37    0       0
09:15:38    40      40
09:15:39    0       0
09:15:39    0       0
09:15:39    0       0
09:15:40    51      51
09:15:40    0       0
09:15:41    250     0
09:15:42    110     0
09:15:43    42      402
09:15:44    0       0
09:15:45    0       0

Body:
Form consecutive groups taking the cumsum of a Boolean mask. Then take the cumsum within each group. Use where to mask everything but the last row within a group (Since cumsum(0) == 0 this works for all 0 rows too) and then we fill the values we masked with 0.

s = df['Value'].eq(0).cumsum()
df['Result'] = (df['Value'].groupby(s).cumsum()
                    .where(~s.duplicated(keep='last'))
                    .fillna(0, downcast='infer'))

        Time  Value  Result
0   09:15:00      0       0
1   09:15:30      0       0
2   09:15:31      0       0
3   09:15:32     85       0
4   09:15:33    168       0
5   09:15:34     50       0
6   09:15:34    100     403
7   09:15:35      0       0
8   09:15:35      0       0
9   09:15:36      0       0
10  09:15:37      0       0
11  09:15:37      0       0
12  09:15:38     40      40
13  09:15:39      0       0
14  09:15:39      0       0
15  09:15:39      0       0
16  09:15:40     51      51
17  09:15:40      0       0
18  09:15:41    250       0
19  09:15:42    110       0
20  09:15:43     42     402
21  09:15:44      0       0
22  09:15:45      0       0


问:
how to serialize list of form object to JSON in django
I'm trying to serialize the form objects and return to the AJAX call so that I can display them in the template, but I'm not able to serialize them unlike serializing the model objects don't we have an option for form objects

```<code>if request.method == 'POST':

    temp_data_form = TemplateDataForm(request.POST)

    if request.POST.get('temp_id'):
        # getting id of the current template
        existing_template = Template.objects.filter(id=request.POST.get('temp_id'))[0]
        if request.POST.get('item'):
            item_query = existing_template.tempdata_set.filter(item=request.POST.get('item'))
            if item_query:
                item_query = item_query[0] and True

        # we only edit the existing object of the template always as we create the object by default on GET request
        if existing_template and existing_template.title != request.POST.get('title') and request.POST.get('title')!= None:
            existing_template.title = request.POST.get('title')
            existing_template.save()
        if temp_data_form.is_valid() and item_query != True:

        # Template items alias data
        td_obj = temp_data_form.save(commit=False)
        td_obj.template = existing_template
        td_obj.save()

        values_form = []

        for item in existing_template.tempdata_set.all():
            values_form.append(TemplateDataForm(instance=item))

        return JsonResponse(values_form, safe=False)
</code>```

I'm getting the below error.

```<code>     raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type TemplateDataForm is not JSON serializable
</code>```

答:
Assuming your TemplateDataForm is a Django form, it should have a "cleaned_data" attribute.  You need to serialize that data and not the form itself.  So for a single form, that would look like the below.  Also, cleaned_data is a dictionary, so you can drop the "safe=False" argument.

```<code>return JsonResponse(values_form.cleaned_data, safe=False)
</code>```

However, based on your code, it looks like you are trying to loop through a child object set or multiple forms.  So, for that, you would probably want to pre-build the json dictionary response in the loop.

```<code>json_response_dict = {}
for item in existing_template.tempdata_set.all():
        values_form.append(TemplateDataForm(instance=item))
        # Add to your response dictionary here.  Assuming you are using
        # django forms and each one is a valid form.  Your key will
        # need to be unique for each loop, so replace 'key' with a
        # loop counter such as 'form' + counter or maybe a form instance
        # cleaned_data pk.  If looping through child set objects, then
        # reference the appropriate attribute such as values_form.title.
        json_response_dict['key'] = values_form.cleaned_data

    return JsonResponse(json_response_dict, safe=False)
</code>```

Then in javascript, for your response, you would need to access each key.

```<code>$.ajax({
        method: 'POST',
        url: yourURL,
        data: yourData
    }).always(function (response) {
        /* Test viewing the title for a single object in dictionary.  Otherwise, loop
         * through the response in each dictionary subset to get the keys/values.
         */
        alert(response.title);
    });
</code>```

Body:
I'm trying to serialize the form objects and return to the AJAX call so that I can display them in the template, but I'm not able to serialize them unlike serializing the model objects don't we have an option for form objects

if request.method == 'POST':

    temp_data_form = TemplateDataForm(request.POST)

    if request.POST.get('temp_id'):
        # getting id of the current template
        existing_template = Template.objects.filter(id=request.POST.get('temp_id'))[0]
        if request.POST.get('item'):
            item_query = existing_template.tempdata_set.filter(item=request.POST.get('item'))
            if item_query:
                item_query = item_query[0] and True

        # we only edit the existing object of the template always as we create the object by default on GET request
        if existing_template and existing_template.title != request.POST.get('title') and request.POST.get('title')!= None:
            existing_template.title = request.POST.get('title')
            existing_template.save()
        if temp_data_form.is_valid() and item_query != True:

        # Template items alias data
        td_obj = temp_data_form.save(commit=False)
        td_obj.template = existing_template
        td_obj.save()

        values_form = []

        for item in existing_template.tempdata_set.all():
            values_form.append(TemplateDataForm(instance=item))

        return JsonResponse(values_form, safe=False)

I'm getting the below error.

     raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type TemplateDataForm is not JSON serializable

Body:
Assuming your TemplateDataForm is a Django form, it should have a "cleaned_data" attribute.  You need to serialize that data and not the form itself.  So for a single form, that would look like the below.  Also, cleaned_data is a dictionary, so you can drop the "safe=False" argument.

return JsonResponse(values_form.cleaned_data, safe=False)

However, based on your code, it looks like you are trying to loop through a child object set or multiple forms.  So, for that, you would probably want to pre-build the json dictionary response in the loop.

json_response_dict = {}
for item in existing_template.tempdata_set.all():
        values_form.append(TemplateDataForm(instance=item))
        # Add to your response dictionary here.  Assuming you are using
        # django forms and each one is a valid form.  Your key will
        # need to be unique for each loop, so replace 'key' with a
        # loop counter such as 'form' + counter or maybe a form instance
        # cleaned_data pk.  If looping through child set objects, then
        # reference the appropriate attribute such as values_form.title.
        json_response_dict['key'] = values_form.cleaned_data

    return JsonResponse(json_response_dict, safe=False)

Then in javascript, for your response, you would need to access each key.

$.ajax({
        method: 'POST',
        url: yourURL,
        data: yourData
    }).always(function (response) {
        /* Test viewing the title for a single object in dictionary.  Otherwise, loop
         * through the response in each dictionary subset to get the keys/values.
         */
        alert(response.title);
    });


问:
Why won't this Linq compile?
In this simplified version of my actual problem, I have two tables: User and Metadata.
Each user can have a varied number of metadata entries associated with them via a FKEY.

This Linq compiles fine:

```<code>var user = from u in Context.Users
           join m in Context.Metadata
           on u.id equals m.userid
           select new { u.id, m.value }
</code>```

However, if I replace the 'on' clause line to be:

```<code>on new { u.id } equals new { m.userid }
</code>```

it fails to compile with this error:

```<code>error CS1941: The type of one of the expressions in the join clause is incorrect.  Type inference failed in the call to 'Join'.
</code>```

Does anyone know why?

And for bonus points:

I'm ultimately trying to accomplish a query like this:

```<code>var user = from u in Context.Users
           join m in Context.Metadata
           on new { u.id, "mystring" } equals new { m.userid, m.key }
           select new { u.id, m.value }
</code>```

Note the use of the literal "mystring".
Needless to say, that doesn't work either.

Thanks!

EDIT: SLaks's answer worked, but just to be fully clear about what he's talking about, the final on clause that works looks like:

```<code>on new { id = u.id, key = "foo" } equals new { id = mu.userid, key = m.key }
</code>```

答:
The property names in your anonymous types must match.

You can specify the names like this: new { UserId = u.id, Key = "mystring" }

Title: Why won't this Linq compile?

Body:
In this simplified version of my actual problem, I have two tables: User and Metadata.
Each user can have a varied number of metadata entries associated with them via a FKEY.

This Linq compiles fine:

var user = from u in Context.Users
           join m in Context.Metadata
           on u.id equals m.userid
           select new { u.id, m.value }

However, if I replace the 'on' clause line to be:

on new { u.id } equals new { m.userid }

it fails to compile with this error:

error CS1941: The type of one of the expressions in the join clause is incorrect.  Type inference failed in the call to 'Join'.

Does anyone know why?

And for bonus points:

I'm ultimately trying to accomplish a query like this:

var user = from u in Context.Users
           join m in Context.Metadata
           on new { u.id, "mystring" } equals new { m.userid, m.key }
           select new { u.id, m.value }

Note the use of the literal "mystring".
Needless to say, that doesn't work either.

Thanks!

EDIT: SLaks's answer worked, but just to be fully clear about what he's talking about, the final on clause that works looks like:

on new { id = u.id, key = "foo" } equals new { id = mu.userid, key = m.key }


问:
Coinbase Pro authentication: No valid signature
I’m attempting to authenticate to Coinbase Pro from a Google Script. I’ve managed to do this already in Postman using CryptoJS, but I’m running into issues generating the CB-ACCESS-SIGN signature header. I’ve set up a test using a test key and secret string to figure out the differences between CryptoJS.HmacSHA256 and Utilities.computeHmacSha256Signature, the implementation Google offers, and noticed a difference in parameters: CryptoJS.HmacSHA256 expects a secret as WordArray while Utilities.computeHmacSha256Signature expects a secret as string.

In Postman I'm doing the following to get the wordarray of my apiSecret to pass to CryptoJS.HmacSHA256:

```<code>var hash = CryptoJS.enc.Base64.parse(pm.variables.get('apiSecret'));
</code>```

In my Google script I'm doing the sam

```<code>var hash = Utilities.base64Decode(apiSecretB64)
</code>```

I've tried debugging this with the same secret and message, but I'm getting different results.

My implementation in Postman:

```<code>function computeSignature(request) {
    const data      = request.data;
    const method    = request.method.toUpperCase();
    const path      = getPath(request.url);
    const body      = (method === 'GET' || !data) ? '' : JSON.stringify(data);
    const message   = timestamp + method + path + body;

    const apiSecret = CryptoJS.enc.Base64.parse(pm.variables.get('apiSecret'));
    const hash      = CryptoJS.HmacSHA256(message, apiSecret);

    const hashInBase64 = CryptoJS.enc.Base64.stringify(hash);

    return hashInBase64;
}
</code>```

And my implementation in Google Script:

```<code>function computeSignature(request, path, timestamp) {
    const data      = request.data;
    const method    = request.method;
    const body      = (method === 'GET' || !data) ? '' : JSON.stringify(data);
    const message   = timestamp + method + path + body;

    var apiSecret = Utilities.base64Decode(apiSecretB64);

    var hash = Utilities.computeHmacSha256Signature(message, apiSecret);
    hash = Utilities.base64Encode(hash);

    return hash;
}
</code>```

Does anyone know why I'm getting different results?

答:
I've managed to solve the issue by converting the message from string to a byte array:

```<code>function computeSignature(request, path, timestamp) {
    const data      = request.data;
    const method    = request.method;
    const body      = (method === 'GET' || !data) ? '' : JSON.stringify(data);
    const message   = timestamp + method + path + body;

    var apiSecretByteArr = Utilities.base64Decode(apiSecretB64);
    var messageByteArr = Utilities.base64Decode(Utilities.base64Encode(message));

    var hash = Utilities.computeHmacSha256Signature(messageByteArr, apiSecretByteArr);

    return Utilities.base64Encode(hash);
}
</code>```

There is probably a better way of doing this, but at least the correct signature is now being computed.

Body:
I’m attempting to authenticate to Coinbase Pro from a Google Script. I’ve managed to do this already in Postman using CryptoJS, but I’m running into issues generating the CB-ACCESS-SIGN signature header. I’ve set up a test using a test key and secret string to figure out the differences between CryptoJS.HmacSHA256 and Utilities.computeHmacSha256Signature, the implementation Google offers, and noticed a difference in parameters: CryptoJS.HmacSHA256 expects a secret as WordArray while Utilities.computeHmacSha256Signature expects a secret as string.

In Postman I'm doing the following to get the wordarray of my apiSecret to pass to CryptoJS.HmacSHA256:

var hash = CryptoJS.enc.Base64.parse(pm.variables.get('apiSecret'));

In my Google script I'm doing the sam

var hash = Utilities.base64Decode(apiSecretB64)

I've tried debugging this with the same secret and message, but I'm getting different results.

My implementation in Postman:

function computeSignature(request) {
    const data      = request.data;
    const method    = request.method.toUpperCase();
    const path      = getPath(request.url);
    const body      = (method === 'GET' || !data) ? '' : JSON.stringify(data);
    const message   = timestamp + method + path + body;

    const apiSecret = CryptoJS.enc.Base64.parse(pm.variables.get('apiSecret'));
    const hash      = CryptoJS.HmacSHA256(message, apiSecret);

    const hashInBase64 = CryptoJS.enc.Base64.stringify(hash);

    return hashInBase64;
}

And my implementation in Google Script:

function computeSignature(request, path, timestamp) {
    const data      = request.data;
    const method    = request.method;
    const body      = (method === 'GET' || !data) ? '' : JSON.stringify(data);
    const message   = timestamp + method + path + body;

    var apiSecret = Utilities.base64Decode(apiSecretB64);

    var hash = Utilities.computeHmacSha256Signature(message, apiSecret);
    hash = Utilities.base64Encode(hash);

    return hash;
}

Does anyone know why I'm getting different results?

Body:
I've managed to solve the issue by converting the message from string to a byte array:

function computeSignature(request, path, timestamp) {
    const data      = request.data;
    const method    = request.method;
    const body      = (method === 'GET' || !data) ? '' : JSON.stringify(data);
    const message   = timestamp + method + path + body;

    var apiSecretByteArr = Utilities.base64Decode(apiSecretB64);
    var messageByteArr = Utilities.base64Decode(Utilities.base64Encode(message));

    var hash = Utilities.computeHmacSha256Signature(messageByteArr, apiSecretByteArr);

    return Utilities.base64Encode(hash);
}

There is probably a better way of doing this, but at least the correct signature is now being computed.


问:
How to get previous/next row when ordering by date/time then ID in MySQL?
I have table like

```<code>SELECT id, name, date FROM `table` ORDER BY `date` DESC, id DESC
...
10  |a|2020-01-08 20:40:00
9   |b|2020-01-08 20:40:00
8   |c|2020-01-08 20:40:00
500 |d|2020-01-06 22:49:00
7   |e|2020-01-06 22:00:00
...
</code>```

How to get next and previous of a record. (ex: i have info of a record with id = 8 then how to get a next record is 9 and a previous record is 500)

答:
You will need to find first of all, current record's position available in the current ordered list, then you will be able to find the previous record as well as next record.

PREVIOUS RECORD

```<code>SELECT row_number, id,name,`date`
FROM (
    SELECT @row := @row + 1 AS row_number, id,name,`date`
    FROM `table` AS t
    JOIN (SELECT @row := 0) r
    ORDER BY `date` DESC, id DESC
) main
WHERE row_number = (
    SELECT current_row - 1
    FROM (
        SELECT @curRow := @curRow + 1 AS current_row, t.id,t.name,t.`date`
        FROM `table` AS t
        JOIN (SELECT @curRow := 0) r
        ORDER BY `date` DESC, id DESC
    ) t1
    WHERE id = 8
);
</code>```

NEXT RECORD

```<code>SELECT row_number, id,name,`date`
FROM (
    SELECT @row := @row + 1 AS row_number, id,name,`date`
    FROM `table` AS t
    JOIN (SELECT @row := 0) r
    ORDER BY `date` DESC, id DESC
) main
WHERE row_number = (
    SELECT current_row + 1
    FROM (
        SELECT @curRow := @curRow + 1 AS current_row, t.id,t.name,t.`date`
        FROM `table` AS t
        JOIN (SELECT @curRow := 0) r
        ORDER BY `date` DESC, id DESC
    ) t1
    WHERE id = 8
);
</code>```

Body:
I have table like

SELECT id, name, date FROM `table` ORDER BY `date` DESC, id DESC
...
10  |a|2020-01-08 20:40:00
9   |b|2020-01-08 20:40:00
8   |c|2020-01-08 20:40:00
500 |d|2020-01-06 22:49:00
7   |e|2020-01-06 22:00:00
...

How to get next and previous of a record. (ex: i have info of a record with id = 8 then how to get a next record is 9 and a previous record is 500)

Body:
You will need to find first of all, current record's position available in the current ordered list, then you will be able to find the previous record as well as next record.

PREVIOUS RECORD

SELECT row_number, id,name,`date`
FROM (
    SELECT @row := @row + 1 AS row_number, id,name,`date`
    FROM `table` AS t
    JOIN (SELECT @row := 0) r
    ORDER BY `date` DESC, id DESC
) main
WHERE row_number = (
    SELECT current_row - 1
    FROM (
        SELECT @curRow := @curRow + 1 AS current_row, t.id,t.name,t.`date`
        FROM `table` AS t
        JOIN (SELECT @curRow := 0) r
        ORDER BY `date` DESC, id DESC
    ) t1
    WHERE id = 8
);

NEXT RECORD

SELECT row_number, id,name,`date`
FROM (
    SELECT @row := @row + 1 AS row_number, id,name,`date`
    FROM `table` AS t
    JOIN (SELECT @row := 0) r
    ORDER BY `date` DESC, id DESC
) main
WHERE row_number = (
    SELECT current_row + 1
    FROM (
        SELECT @curRow := @curRow + 1 AS current_row, t.id,t.name,t.`date`
        FROM `table` AS t
        JOIN (SELECT @curRow := 0) r
        ORDER BY `date` DESC, id DESC
    ) t1
    WHERE id = 8
);


问:
How to handle system crash when using Apache Camel and ActiveMQ
I have Apache Camel with ActiveMQ to do batch processing of size 1000. My understanding is apache camel will retrieve 1000 data FROM the queue and process it then it will push to TO queue once processing is done. My question is what happens if a system in which processing these data crashes before pushing the TO queue. Does this data remain in the ActiveMQ or it is lost forever.

In scenarios without Apache camel, we can configure the listener with different acknowledgment modes like CLIENT_ACKNOWLEDGE.

Is there anything like this in Apache camel. Below is my JMS Config class

```<code>public class JMSConfig {

    private Environment env;

    public JMSConfig(Environment env) {
        this.env = env;
    }

    @Bean
    public ConnectionFactory connectionFactory() {
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory();
        return connectionFactory;
    }

    @Bean
    public JmsTransactionManager geJmsTransactionManager(final ConnectionFactory connectionFactory) {
        JmsTransactionManager jmsTransactionManager = new JmsTransactionManager();
        jmsTransactionManager.setConnectionFactory(connectionFactory);
        return jmsTransactionManager;
    }

    @Bean
    public JmsComponent createJmsComponent(final ConnectionFactory connectionFactory, final JmsTransactionManager jmsTransactionManager) {
        JmsComponent jmsComponent = JmsComponent.jmsComponentTransacted(connectionFactory, jmsTransactionManager);
        return jmsComponent;
    }
}
</code>```

答:
Good morning,

I have been meaning to reply to your question for a while now, apologies for the delay.

I will be discussing Dups-OK message transfers with local JMS transactions.  This means that the JMS send and receive sessions will use local JMS transactions.  These two independent local transactions will be synchronized by a JTA transaction manager.  With JTA synchronized transactions, the commit for the 'put' must be acknowledged before the 'get'  is acknowledged.

But first, some thoughts on using ActiveMQs message prefetch in this scenario.  By default, out of the box, A-MQ will 'prefetch' 1000 messages when a recieve() call is made on a session.  This presumes that the client code is going to leave the message listener up and consume all 1000 messages.  If the client code just reads 1 message, for example, and then closes the session, 999 messages have to be returned to the source queue.  Or, if something bad is happening, transactions may be failing and thrashing the prefetch.

I can go on with this topic at length, but just know that the Spring JMS code does not play well with transactional Camel routes and message prefetch, and I will be disabling prefetch in my example.  Note that message prefetching is a performance optimization, so getting a route working without prefetch is a good thing.  You may then find out that the message prefetch can increase performance, but has very undesirable side effects.

You did not mention your platform, I will be discussing a Blueprint XML file.  This is very similar to a standard Camel/Spring XML file:

Blueprint Camel Route

As I am working on an OSGi platform, I have Aries installed by default as the Platform Transaction Manager, and Aries is a JTA transaction manager.  If you are in Spring Boot, for example, you may need to include a starter like:

```<code>    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jta-narayana</artifactId>
    </dependency>
</code>```

In order to have a JTA PlatformTransactionManager (Arjuna, in this case).  Do not instantiate a JmsTransactionManager and assign it as the PlatformTransactionManager.

Looking at the code, note:

```<code><property name="brokerURL" value="tcp://10.0.0.170:61616?jms.prefetchPolicy.all=0"/>
</code>```

This is disabling the message prefetching.

Note that I do not explicitly reference any transaction managers.  Setting:

```<code><property name="transacted" value="true"/>
</code>```

will create a JmsTransactionManager for you.

Then the line:

```<code> <transacted id="trans"/>
</code>```

will start a JTA transaction context.  The two local JMS transactions will be synchronized, and you may get duplicate messages, but you will not lose messages.

Add some logging:

```<code><logger name="org.apache.camel" level="DEBUG" additivity="false">
    <appender-ref ref="STDOUT" />
</logger>

<logger name="org.springframework.jms.connection.JmsTransactionManager" level="DEBUG" additivity="false">
    <appender-ref ref="STDOUT" />
</logger>

<logger name="org.apache.activemq.TransactionContext" level="DEBUG" additivity="false">
    <appender-ref ref="STDOUT" />
</logger>
</code>```

Or maybe:

```<code><logger name="com.arjuna" level="TRACE" additivity="false">
    <appender-ref ref="STDOUT" />
</logger>
</code>```

If you are using Arjuna.

You should see the two commits back-to-back.  This gives a very small window where a failure can result in duplicate message delivery.

I would highly recommend starting with my example as verbatim as possible.  Even small deviations can have very unexpected results.

Body:
I have Apache Camel with ActiveMQ to do batch processing of size 1000. My understanding is apache camel will retrieve 1000 data FROM the queue and process it then it will push to TO queue once processing is done. My question is what happens if a system in which processing these data crashes before pushing the TO queue. Does this data remain in the ActiveMQ or it is lost forever.

In scenarios without Apache camel, we can configure the listener with different acknowledgment modes like CLIENT_ACKNOWLEDGE.

Is there anything like this in Apache camel. Below is my JMS Config class

public class JMSConfig {

    private Environment env;

    public JMSConfig(Environment env) {
        this.env = env;
    }

    @Bean
    public ConnectionFactory connectionFactory() {
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory();
        return connectionFactory;
    }

    @Bean
    public JmsTransactionManager geJmsTransactionManager(final ConnectionFactory connectionFactory) {
        JmsTransactionManager jmsTransactionManager = new JmsTransactionManager();
        jmsTransactionManager.setConnectionFactory(connectionFactory);
        return jmsTransactionManager;
    }

    @Bean
    public JmsComponent createJmsComponent(final ConnectionFactory connectionFactory, final JmsTransactionManager jmsTransactionManager) {
        JmsComponent jmsComponent = JmsComponent.jmsComponentTransacted(connectionFactory, jmsTransactionManager);
        return jmsComponent;
    }
}

Body:
Good morning,

I have been meaning to reply to your question for a while now, apologies for the delay.

I will be discussing Dups-OK message transfers with local JMS transactions.  This means that the JMS send and receive sessions will use local JMS transactions.  These two independent local transactions will be synchronized by a JTA transaction manager.  With JTA synchronized transactions, the commit for the 'put' must be acknowledged before the 'get'  is acknowledged.

But first, some thoughts on using ActiveMQs message prefetch in this scenario.  By default, out of the box, A-MQ will 'prefetch' 1000 messages when a recieve() call is made on a session.  This presumes that the client code is going to leave the message listener up and consume all 1000 messages.  If the client code just reads 1 message, for example, and then closes the session, 999 messages have to be returned to the source queue.  Or, if something bad is happening, transactions may be failing and thrashing the prefetch.

I can go on with this topic at length, but just know that the Spring JMS code does not play well with transactional Camel routes and message prefetch, and I will be disabling prefetch in my example.  Note that message prefetching is a performance optimization, so getting a route working without prefetch is a good thing.  You may then find out that the message prefetch can increase performance, but has very undesirable side effects.

You did not mention your platform, I will be discussing a Blueprint XML file.  This is very similar to a standard Camel/Spring XML file:

Blueprint Camel Route

As I am working on an OSGi platform, I have Aries installed by default as the Platform Transaction Manager, and Aries is a JTA transaction manager.  If you are in Spring Boot, for example, you may need to include a starter like:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jta-narayana</artifactId>
    </dependency>

In order to have a JTA PlatformTransactionManager (Arjuna, in this case).  Do not instantiate a JmsTransactionManager and assign it as the PlatformTransactionManager.

Looking at the code, note:

<property name="brokerURL" value="tcp://10.0.0.170:61616?jms.prefetchPolicy.all=0"/>

This is disabling the message prefetching.

Note that I do not explicitly reference any transaction managers.  Setting:

<property name="transacted" value="true"/>

will create a JmsTransactionManager for you.

Then the line:

 <transacted id="trans"/>

will start a JTA transaction context.  The two local JMS transactions will be synchronized, and you may get duplicate messages, but you will not lose messages.

Add some logging:

<logger name="org.apache.camel" level="DEBUG" additivity="false">
    <appender-ref ref="STDOUT" />
</logger>

<logger name="org.springframework.jms.connection.JmsTransactionManager" level="DEBUG" additivity="false">
    <appender-ref ref="STDOUT" />
</logger>

<logger name="org.apache.activemq.TransactionContext" level="DEBUG" additivity="false">
    <appender-ref ref="STDOUT" />
</logger>

Or maybe:

<logger name="com.arjuna" level="TRACE" additivity="false">
    <appender-ref ref="STDOUT" />
</logger>

If you are using Arjuna.

You should see the two commits back-to-back.  This gives a very small window where a failure can result in duplicate message delivery.

I would highly recommend starting with my example as verbatim as possible.  Even small deviations can have very unexpected results.