Sunday, November 12, 2023

Batch Script : The mystery of setting variable inside for loop

 Spend whole day to figure out how to get a random terms inside for loop.


Tried %%list[!index!]%% , %list[!index!]% , !list[%index%]! many many combination. 

Finally, a "call" made the magic.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
@echo off

setlocal enabledelayedexpansion



REM Define the list

set "list[0]=a"

set "list[1]=b"

set "list[2]=c"



REM Enable delayed expansion within the loop

for /l %%i in (1,1,3) do (

    REM Generate a random index within the range of the list

    set /a "index=!random! %% 3"

    

    REM without that call, cannot get the string

    call set "randomString=%%list[!index!]%%"

    

    REM Print the iteration number and the corresponding random string

    echo Random string for iteration %%i: !randomString!

)



endlocal

Tuesday, August 22, 2023

Colab Python web service : Cannot get expected return with json passing to REST API

Another silly mistake I made due carelessness .
I spent certain hours to just figure out the root-cause : Missing json.dumps when I pass the data.
Originally, I think put json content in header is OK...


#Call Rest API with json data
import requests
import json
import os

baseUrl = 'endpointAddr/api-link'

#Parameters
data = {
   "id":"1234568",
   "currency":"HKD",
   "amount":"1000"
}




#function to call
def callAPI():
    response = requests.post(baseUrl,headers={"Content-Type": "application/json","Authorization": "Bearer xxxxxxxxxxxxxxx"}, data=json.dumps(data))

    if response.status_code == 200:
       print('Access token test :' , response.json())
       authToken = response.json()['access_token']
       print('Access token:', authToken)
       return (authToken)
    else:
        print('Login failed with status code:', response.status_code , response.text)
        return (0)


#Main
response1 = callAPI()
print ('response 1 ' + response1)

Wednesday, August 2, 2023

Python Coding : Call Salesforce API using OAuth 2.0 JWT Bearer token Flow 以 Python 代碼實現Salesforce JWT 伺服器簽名驗證

Prequisites : Setup Connected App with  X509 Certification.

預設需要先在Salesforce 上載X509證書。詳細設定連接。(可接受自行簽署版本證書)

Details Set up in Salesforce side : link



#POC of JWT call to API#Colab install library with >> !pip install pyJWT[crypto]

import jwt
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
import time
import requests
import json

expTime = int(time.time()) + 900  #Unix Epoch Timestamp Expire time. 15mins buffer
jwt_algorithm = 'RS256'
jwt_private_key_file = '/myPath/server.key'
jwt_payload = {
  "iss": "clientid",
  "sub": "salesforce_username_email",
  "aud": "https://test.salesforce.com",
  "exp": expTime
}

jwt_header = {
  "alg": "RS256",
  "typ": "JWT"
}
salesforceEndpoint = 'https://test.salesforce.com/services/oauth2/token'
api_endpoint = 'https://instance_domain.my.salesforce.com/services/data/v57.0/sobjects/myObject__c'

test_data={
    "description": "PythonSent",
    "language": "en",
    "remarks": "xxx",
    "expiry_time": expTime+900,
    "created_time": expTime
}


def loginSfdc():
    # Load the private key 
    with open(jwt_private_key_file, 'r') as f:
        jwt_private_key = f.read()

    # Generate the JWT token
    jwt_token = jwt.encode(jwt_payload, jwt_private_key, algorithm=jwt_algorithm,headers=jwt_header)
    print('token : ' + jwt_token);
    salesforceUrlParams = {
        'grant_type' : 'urn:ietf:params:oauth:grant-type:jwt-bearer',
        'assertion' :jwt_token
    }

    response = requests.post(salesforceEndpoint, params=salesforceUrlParams, verify=False)

    if response.status_code == 200:
        authToken = response.json()['access_token']
        print('return token ' + authToken)
        return authToken
    else:
        print('Request failed with status code:', response.status_code)
        print('Request failed with status code:', response.text)
        return(0)

#function to call
def callSfdc_pocApi(authToken):
    session = requests.Session()
    rheaders = {
    'Authorization': 'Bearer ' + authToken,
    'Content-Type': 'application/json'
    }
   
    response = requests.post(api_endpoint,headers=rheaders, data=json.dumps(test_data))
    returnStr = ''
    if response.status_code == 200:
        data = response.json()
        returnStr = data
    else:
        print('Request failed with status code:', response.text)
        returnStr = response.status_code

    return returnStr

#Main
response1 = loginSfdc()
if not response1 == 0:
    response2 = callSfdc_pocApi(response1)
    print ("OK")
    print(response2)
else:
    print ('Failed to Login')

Thursday, June 29, 2023

超老舊軟體PhotoImpact X3走在Window 10 , 停止在 "正在初始化主要視窗及元件"階段 . 錯誤碼0xc0000005解決方法

一直在Window 10 (64bit) 上使用PhotoImpact X3 都好好的,今天突然開不到。
查了很多資料,最後發現是暫存檔的問題。

把以下位置中所有今天才生成的檔案移走,重開就行了。
C:\Users\YOUR_NAME\AppData\Roaming\Ulead Systems\Ulead PhotoImpact\13.0\Ulead.DAT\

從中學開始用了PhotoImpact 系列20年,升學及工作都多用Photoshop,但自用時還是更喜歡輕量易用的PhotoImpact 呢!~

Saturday, April 1, 2023

C# coding : Download Salesforce attachment to local disk using SOAP webservice Enterprise wsdl method (with SOQL selection)

Pre-requisite :

  • Select Target framework to 4.5.2 
  • Install DeveloperForce.Force 2.1.0 (via nuget if VS2015 is used)
  • Import Enterprise wsdl as WebReference (for easy Type Casting , partner wsdl also work but need more code lines.)
  • Update 2 ListViewRecordColumn[][] in Reference.cs to ListViewRecordColumn[].
    Otherwise, error  as below will be shown :
    Cannot convert type 'SaleForceBase.SaleForceRef.ListViewRecordColumn[]' ...

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Salesforce;
using System.IO;
using ConsoleApplication1.SfService;

namespace ConsoleApplication1

{
    class Program
    {
        static void Main(string[] args)
        {

            System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Ssl3 | System.Net.SecurityProtocolType.Tls12;//Added to fix he request was aborted could not create ssl/tls secure channel.

            //Get Salesforce credentials
            var username = "your_salesforce_username";
            var password = "your_salesforce_password";
	   //var token = "your_salesforce_security_token";//uncomment this if you have enabled security token function. 

            var authEndpoint = "https://login.salesforce.com/services/Soap/u/50.0";

            // Login to Salesforce using SOAP API

            var binding = new SforceService();

            try {

            var loginResult = binding.login(username, password);
	    //var loginResult = binding.login(username, password + your_salesforce_security_token); //use this instead of above to login if you have enabled security token function. 
            binding.Url = loginResult.serverUrl;
            binding.SessionHeaderValue = new SessionHeader { sessionId = loginResult.sessionId };

            // Query for to get 5 attachments related to Account object

            var attachmentQuery = "SELECT Id, Name, ParentId FROM Attachment WHERE Parent.Type = 'Account' ORDER BY ParentId limit 5";
            var queryResult = binding.query(attachmentQuery);

            // Loop through the results and download each attachment

            foreach (var sObject in queryResult.records)

            {

                var attachment = (Attachment)sObject;//retrieve(string fieldList, string sObjectType, ID ids[]);
                var account = (Account)binding.retrieve("Name", "Account", new string[] { attachment.ParentId })[0];//returned as sObject[] , so need to get [0] 

                // Create a file name for the attachment

                var fileName = $"{account.Name} - {attachment.Name}";

                // Download the attachment

                var attachmentBody = (Attachment)binding.retrieve("Body" ,"Attachment",  new string[] { attachment.Id })[0];
                File.WriteAllBytes(fileName, attachmentBody.Body);
				
            }
            }
            catch(Exception ex)
            {
                System.Diagnostics.Debug.WriteLine("Error : " + ex.InnerException);
                System.Diagnostics.Debug.WriteLine("Error2 : " + ex.StackTrace);
                System.Diagnostics.Debug.WriteLine("Error3 : " + ex.Message);
            }
        }
    }
}

 

Thursday, March 16, 2023

Colab : ImportError cannot import name 'rank_zero_only' from 'pytorch_lightning.utilities.distributed' (Stable Diffusion WebUI related) AI生成圖片Colab偵錯

When I am trying to use Colab for stable diffusion ,
I met error below today :

ImportError cannot import name 'rank_zero_only' from 'pytorch_lightning.utilities.distributed'


After searching , I got the answer finally from here.

Changed From : from pytorch_lightning.utilities.distributed import rank_zero_only 


To : from pytorch_lightning.utilities.rank_zero import rank_zero_only 


Before Run , remember to downgrade !pip install pydantic==1.10.11





So I updated the line 20 in file ddpm.py as indicated in debug log, and the issue is resolved. 




Friday, January 13, 2023

Salesforce concept : Limitation of Rollup Summary and Validation Rule

Question : Rollup summary CANNOT be used in formula field ?
Answer : No .
Rollup Summary can be used to group field values of child record .

Even thought it is formula type field , however ,
grouped field values CANNOT be cross-object formula field.


Question : How to validate the field values changed by Approval process ?
Answer : Validation is NOT a choice . Since field update fired by approval process will NOT initiate validation rule. (More explicit answer from google  , Validation Rules fire before workflow rules, so the record has to meet the validation rule criteria before the workflows get a chance to run. So, the validation rule will not work when you update the workflow field.)

Tigger can be used to validate the field values changed by approval process.

Migrating from Renpy to Godot

 Due to the limitation of renpy in rendering dynamic screen ,  due the the black border it gives in different UI scale resolution , finally ...