I just need to decode a URL, for example, replace %2E with .
I can hack out a method if one isn't build in, but my assumption is that there must be a URL decoding tool already existing.
Here's a snippet I wrote years ago
-markus
Public Function URLDecode(sEncodedURL As String) As String
On Error GoTo Catch
Dim iLoop As Integer
Dim sRtn As String
Dim sTmp As String
If Len(sEncodedURL) > 0 Then
' Loop through each char
For iLoop = 1 To Len(sEncodedURL)
sTmp = Mid(sEncodedURL, iLoop, 1)
sTmp = Replace(sTmp, "+", " ")
' If char is % then get next two chars
' and convert from HEX to decimal
If sTmp = "%" and LEN(sEncodedURL) + 1 > iLoop + 2 Then
sTmp = Mid(sEncodedURL, iLoop + 1, 2)
sTmp = Chr(CDec("&H" & sTmp))
' Increment loop by 2
iLoop = iLoop + 2
End If
sRtn = sRtn & sTmp
Next
URLDecode = sRtn
End If
Finally:
Exit Function
Catch:
URLDecode = ""
Resume Finally
End Function
No.
But here's one: URL Encoder and Decoder for VB
Or something along the lines of (possibly not complete):
Public Function URLDecode(ByVal strEncodedURL As String) As String
Dim str As String
str = strEncodedURL
If Len(str) > 0 Then
str = Replace(str, "&", " & ")
str = Replace(str, "", Chr(39))
str = Replace(str, "&quo", Chr(34))
str = Replace(str, "+", " ")
str = Replace(str, "%2A", "*")
str = Replace(str, "%40", "#")
str = Replace(str, "%2D", "-")
str = Replace(str, "%5F", "_")
str = Replace(str, "%2B", "+")
str = Replace(str, "%2E", ".")
str = Replace(str, "%2F", "/")
URLDecode = str
End If
End Function
Also, take a look at How can I URL encode a string in Excel VBA?
EncodeURL and DecodeURL function using htmlfile object(Late binding)
I got this source from this site: http://cocosoft.kr/442
Function ENCODEURL(varText As Variant, Optional blnEncode = True)
Static objHtmlfile As Object
If objHtmlfile Is Nothing Then
Set objHtmlfile = CreateObject("htmlfile")
With objHtmlfile.parentWindow
.execScript "function encode(s) {return encodeURIComponent(s)}", "jscript"
End With
End If
If blnEncode Then
ENCODEURL = objHtmlfile.parentWindow.encode(varText)
End If
End Function
Function DECODEURL(varText As Variant, Optional blnEncode = True)
Static objHtmlfile As Object
If objHtmlfile Is Nothing Then
Set objHtmlfile = CreateObject("htmlfile")
With objHtmlfile.parentWindow
.execScript "function decode(s) {return decodeURIComponent(s)}", "jscript"
End With
End If
If blnEncode Then
DECODEURL = objHtmlfile.parentWindow.decode(varText)
End If
End Function
For example,
str = ENCODEURL("/?&=") 'returns "%2F%3F%26%3D"
str = DECODEURL("%2F%3F%26%3D") 'returns "/?&="
Here is the code from the URL posted in another answer in case it goes down as it works great.
http://www.freevbcode.com/ShowCode.asp?ID=1512
Public Function URLEncode(StringToEncode As String, Optional _
UsePlusRatherThanHexForSpace As Boolean = False) As String
Dim TempAns As String
Dim CurChr As Integer
CurChr = 1
Do Until CurChr - 1 = Len(StringToEncode)
Select Case Asc(Mid(StringToEncode, CurChr, 1))
Case 48 To 57, 65 To 90, 97 To 122
TempAns = TempAns & Mid(StringToEncode, CurChr, 1)
Case 32
If UsePlusRatherThanHexForSpace = True Then
TempAns = TempAns & "+"
Else
TempAns = TempAns & "%" & Hex(32)
End If
Case Else
TempAns = TempAns & "%" & _
Format(Hex(Asc(Mid(StringToEncode, _
CurChr, 1))), "00")
End Select
CurChr = CurChr + 1
Loop
URLEncode = TempAns
End Function
Public Function URLDecode(StringToDecode As String) As String
Dim TempAns As String
Dim CurChr As Integer
CurChr = 1
Do Until CurChr - 1 = Len(StringToDecode)
Select Case Mid(StringToDecode, CurChr, 1)
Case "+"
TempAns = TempAns & " "
Case "%"
TempAns = TempAns & Chr(Val("&h" & _
Mid(StringToDecode, CurChr + 1, 2)))
CurChr = CurChr + 2
Case Else
TempAns = TempAns & Mid(StringToDecode, CurChr, 1)
End Select
CurChr = CurChr + 1
Loop
URLDecode = TempAns
End Function
' URLDecode function in Perl for reference
' both VB and Perl versions must return same
'
' sub urldecode{
' local($val)=#_;
' $val=~s/\+/ /g;
' $val=~s/%([0-9A-H]{2})/pack('C',hex($1))/ge;
' return $val;
' }
Related
I am trying to execute the following script and getting the below error. Redis is running in docker
Exception in thread "main" org.redisson.client.RedisException: ERR
user_script:1: Script attempted to access nonexistent global variable
'print' script: 6f736423f082e141036b833d1f86b5a36a494611, on
#user_script:1..
I get the same error when I execute using redis CLI
127.0.0.1:6379> eval "print("Comparison is_made b/w minimum_value out of two is: ")" 0 (error) ERR user_script:1: Script attempted to
access nonexistent global variable 'print' script:
8598b7f0db450c711d3a9e73a296e331bd1ef945, on #user_script:1.
127.0.0.1:6379>
Java code. I am using Redison lib to connect to Redis and execute script.
String script = "local rate = redis.call('hget', KEYS[1], 'rate');"
+ "local interval = redis.call('hget', KEYS[1], 'interval');"
+ "local type = redis.call('hget', KEYS[1], 'type');"
+ "assert(rate ~= false and interval ~= false and type ~= false, 'RateLimiter is not initialized')"
+ "local valueName = KEYS[2];"
+ "local permitsName = KEYS[4];"
+ "if type == '1' then "
+ "valueName = KEYS[3];"
+ "permitsName = KEYS[5];"
+ "end;"
+"print(\"rate\"..rate) ;"
+"print(\"interval\"..interval) ;"
+"print(\"type\"..type); "
+ "assert(tonumber(rate) >= tonumber(ARGV[1]), 'Requested permits amount could not exceed defined rate'); "
+ "local currentValue = redis.call('get', valueName); "
+ "local res;"
+ "if currentValue ~= false then "
+ "local expiredValues = redis.call('zrangebyscore', permitsName, 0, tonumber(ARGV[2]) - interval); "
+ "local released = 0; "
+ "for i, v in ipairs(expiredValues) do "
+ "local random, permits = struct.unpack('Bc0I', v);"
+ "released = released + permits;"
+ "end; "
+ "if released > 0 then "
+ "redis.call('zremrangebyscore', permitsName, 0, tonumber(ARGV[2]) - interval); "
+ "if tonumber(currentValue) + released > tonumber(rate) then "
+ "currentValue = tonumber(rate) - redis.call('zcard', permitsName); "
+ "else "
+ "currentValue = tonumber(currentValue) + released; "
+ "end; "
+ "redis.call('set', valueName, currentValue);"
+ "end;"
+ "if tonumber(currentValue) < tonumber(ARGV[1]) then "
+ "local firstValue = redis.call('zrange', permitsName, 0, 0, 'withscores'); "
+ "res = 3 + interval - (tonumber(ARGV[2]) - tonumber(firstValue[2]));"
+ "else "
+ "redis.call('zadd', permitsName, ARGV[2], struct.pack('Bc0I', string.len(ARGV[3]), ARGV[3], ARGV[1])); "
+ "redis.call('decrby', valueName, ARGV[1]); "
+ "res = nil; "
+ "end; "
+ "else "
+ "redis.call('set', valueName, rate); "
+ "redis.call('zadd', permitsName, ARGV[2], struct.pack('Bc0I', string.len(ARGV[3]), ARGV[3], ARGV[1])); "
+ "redis.call('decrby', valueName, ARGV[1]); "
+ "res = nil; "
+ "end;"
+ "local ttl = redis.call('pttl', KEYS[1]); "
+ "if ttl > 0 then "
+ "redis.call('pexpire', valueName, ttl); "
+ "redis.call('pexpire', permitsName, ttl); "
+ "end; "
+ "return res;";
RedissonClient client = null;
try {
client = Redisson.create();
client.getRateLimiter("user1:endpoint1").setRate(
RateType.PER_CLIENT, 5, 1, RateIntervalUnit.SECONDS);
String sha1 = client.getScript().scriptLoad(script);
List<Object> keys =
Arrays.asList("user1:endpoint1", "{user1:endpoint1}:value",
"{user1:endpoint1}:value:febbb04d-6365-4cb8-b32b-8d90800cd4e6",
"{user1:endpoint1}:permits", "{user1:endpoint1}:permits:febbb04d-6365-4cb8-b32b-8d90800cd4e6");
byte[] random = new byte[8];
ThreadLocalRandom.current().nextBytes(random);
Object args[] = {1, System.currentTimeMillis(), random};
boolean res = client.getScript().evalSha(READ_WRITE, sha1, RScript.ReturnType.BOOLEAN, keys, 1,
System.currentTimeMillis(), random);
System.out.println(res);
}finally {
if(client != null && !client.isShutdown()){
client.shutdown();
}
}
checked the Lua print on the same line thread but io.write also is giving same error.
As in the comments wrote return() seems* the only way.
Example for redis-cli (set redis DB and use it in Lua)
(Collect Data and return as one string)
set LuaV 'local txt = "" for k, v in pairs(redis) do txt = txt .. tostring(k) .. " => " .. tostring(v) .. " | " end return(txt)'
Now the eval
eval "local f = redis.call('GET', KEYS[1]) return(loadstring(f))()" 1 LuaV
...shows whats in table: redis
(One long String no \n possible)
Exception: eval 'redis.log(2, _VERSION)' 0 gives out without ending the script but only on the server.
Than \n will work when you do...
set LuaV 'local txt = "" for k, v in pairs(redis) do txt = txt .. tostring(k) .. " => " .. tostring(v) .. "\n" end return(txt)'
...and the eval
eval 'local f = redis.call("GET", KEYS[1]) f = loadstring(f)() redis.log(2, f)' 1 LuaV
start = io.read()
if start == "start" then
xpr = 50
xp = 75
function level()
if xp >= xpr and level < 50 then
xpr = xpr * 1.5
level = level + 1
io.write("Congrats you somehow didn't die and lose every bit of progress!", "\n")
io.write("By the way your level is ", level, "\n")
io.write("Now you must allocate your skill points now", "\n")
sp = 6
io.write("Strength: ", "\n")
strsp = io.read()
stre = stre + strsp
if strsp < sp then
io.write("There are only",sp,"skill points", "\n")
str = str + 6
end
io.write("Dexterity: ", "\n")
dexsp = io.read()
dex = dex + dexsp
if dexsp < sp then
io.write("There are only",sp,"skill points", "\n")
dex = dex + 6
end
io.write("Constuion: ", "\n")
consp = io.read()
con = con + consp
if consp < sp then
io.write("There are only",sp,"skill points", "\n")
con = con + 6
end
io.write("Intelligence: ", "\n")
intsp = io.read()
int = int + intsp
if intsp < sp then
io.write("There are only",sp,"skill points", "\n")
int = int + 6
end
io.write("Wisdom: ", "\n")
wissp = io.read()
wis = wis + wissp
if wissp < sp then
io.write("There are only",sp,"skill points", "\n")
wis = wis + 6
end
io.write("Charisma: ", "\n")
chasp = io.read()
cha = cha + chasp
if chasp < sp then
io.write("There are only",sp,"skill points", "\n")
cha = cha + 6
end
end
end
end
print(level(xp))
This is my code. But it comes back as
lua: attempt to compare function with number
How can I fix this?
Comparing a function with a number doesn't make any sense.
function level() end is syntactic sugar for level = function () end. Just in case you're wondering why level is a function value.
level < 50 compares your global function level with 50.
You call level(xp) but level doesn't have any parameters btw.
Either rename the function or the variable you want to compare with 50.
Either way you need to initialize that variable with a number value or you'll get an error for comparing nil with a number.
I am writing a small function that will calculate the contents of a TextBox after the KeyPress event, but during the KeyPress event. I know, it sounds strange. :)
The reason for this is because I have been given a project at work, where I am to fix any errors in a current program.
There is currently a TextBox, which triggers a search on a SQL Server, in the KeyPress event.
This searches for the current contents of the TextBox concatenated with Chr(KeyAscii)
This means that if your TextBox contains Hello and your cursor is at the end of the word it will work correctly, but if you have the o selected and press a it will search for Helloa instead of Hella.
So to correct, this I have come up with the following function
Private Function TextAfterKeyPress(Ctrl As Control, KeyAscii As Integer) As String
Dim strUnSelLeft As String
Dim strUnSelRight As String
Dim strSel As String
Dim strMid As String
With Ctrl
strUnSelLeft = ""
strUnSelRight = ""
strMid = .Text
Select Case KeyAscii
Case 1 ' Ctrl + A
' No change to text
Case 3 ' Ctrl + C
' No change to text
Case 8 ' BackSpace
If .SelStart = 0 Then
' No change to text
Else
If .SelLength = 0 Then
strUnSelLeft = Left(.Text, .SelStart - 1)
strUnSelRight = Right(.Text, Len(.Text) - (.SelStart + .SelLength))
strMid = ""
Else
strUnSelLeft = Left(.Text, .SelStart)
strUnSelRight = Right(.Text, Len(.Text) - (.SelStart + .SelLength))
strMid = ""
End If
End If
Case 9 ' Tab
' No change to text
Case 13 ' Return
' No change to text
Case 22 ' Ctrl + V
strUnSelLeft = Left(.Text, .SelStart)
strUnSelRight = Right(.Text, Len(.Text) - (.SelStart + .SelLength))
strMid = Clipboard.GetText
Case 24 ' Ctrl + X
If .SelLength = 0 Then
' No change to text
Else
strUnSelLeft = Left(.Text, .SelStart)
strUnSelRight = Right(.Text, Len(.Text) - (.SelStart + .SelLength))
strMid = ""
End If
Case 26 ' Ctrl + Z
Case 27 ' Esc
' No Change to text
Case 137, 153, 160, 169, 188, 189, 190, 215, 247 ' Disallowed Chars
' No Change to text
Case 128 To 255 ' Allowed non standard Chars
strUnSelLeft = Left(.Text, .SelStart)
strUnSelRight = Right(.Text, Len(.Text) - (.SelStart + .SelLength))
strMid = Chr(KeyAscii)
Case 32 To 127 ' Standard Printable Chars
strUnSelLeft = Left(.Text, .SelStart)
strUnSelRight = Right(.Text, Len(.Text) - (.SelStart + .SelLength))
strMid = Chr(KeyAscii)
Case Else
End Select
TextAfterKeyPress = strUnSelLeft & strMid & strUnSelRight
End With
End Function
Now for the section where it says "Case 26", it will perform an undo action, and then the search won't work correctly again.
Is there any way to find out what the contents of the TextBox will be when you press Ctrl + Z, but during the KeyPress in which it happens? The KeyPress event fires before the content of the TextBox changes so I would need to find out what is in the Undo buffer so that I can run a correct search.
Can anyone point me in the right direction?
I have worked with textbox APIs a bit ..And i don't think you can deal with its UNDO buffer due to its limitation.. but something you can do is to manually send an UNDO then read the textbox content.
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Const EM_UNDO = &HC7
,
Case 26
KeyAscii = 0
SendMessage .hwnd, EM_UNDO, ByVal 0, ByVal 0
strMid = .Text
If you only need to read the text and not to change it you can send an another UNDO msg to get the text to its previous content.
Parsing nested indented text into lists
Hi,
maybe someone can give me a start help.
I have nested indented txt similar to this. I should parse that into a nested list structure like
TXT = r"""
Test1
NeedHelp
GotStuck
Sometime
NoLuck
NeedHelp2
StillStuck
GoodLuck
"""
Nested_Lists = ['Test1',
['NeedHelp',
['GotStuck',
['Sometime',
'NoLuck']]],
['NeedHelp2',
['StillStuck',
'GoodLuck']]
]
Nested_Lists = ['Test1', ['NeedHelp', ['GotStuck', ['Sometime', 'NoLuck']]], ['NeedHelp2', ['StillStuck', 'GoodLuck']]]
Any help for python3 would be appriciated
You could exploit Python tokenizer to parse the indented text:
from tokenize import NAME, INDENT, DEDENT, tokenize
def parse(file):
stack = [[]]
lastindent = len(stack)
def push_new_list():
stack[-1].append([])
stack.append(stack[-1][-1])
return len(stack)
for t in tokenize(file.readline):
if t.type == NAME:
if lastindent != len(stack):
stack.pop()
lastindent = push_new_list()
stack[-1].append(t.string) # add to current list
elif t.type == INDENT:
lastindent = push_new_list()
elif t.type == DEDENT:
stack.pop()
return stack[-1]
Example:
from io import BytesIO
from pprint import pprint
pprint(parse(BytesIO(TXT.encode('utf-8'))), width=20)
Output
['Test1',
['NeedHelp',
['GotStuck',
['Sometime',
'NoLuck']]],
['NeedHelp2',
['StillStuck',
'GoodLuck']]]
I hope you can understand my solution. If not, ask.
def nestedbyindent(string, indent_char=' '):
splitted, i = string.splitlines(), 0
def first_non_indent_char(string):
for i, c in enumerate(string):
if c != indent_char:
return i
return -1
def subgenerator(indent):
nonlocal i
while i < len(splitted):
s = splitted[i]
title = s.lstrip()
if not title:
i += 1
continue
curr_indent = first_non_indent_char(s)
if curr_indent < indent:
break
elif curr_indent == indent:
i += 1
yield title
else:
yield list(subgenerator(curr_indent))
return list(subgenerator(-1))
>>> nestedbyindent(TXT)
['Test1', ['NeedHelp', ['GotStuck', ['Sometime', 'NoLuck']],
'NeedHelp2',['StillStuck', 'GoodLuck']]]
Here is the answer that is very non-Pythonic and verbose way. But it seems to work.
TXT = r"""
Test1
NeedHelp
GotStuck
Sometime
NoLuck
NeedHelp2
StillStuck
GoodLuck
"""
outString = '['
level = 0
first = 1
for i in TXT.split("\n")[1:]:
count = 0
for j in i:
if j!=' ':
break
count += 1
count /= 4 #4 space = 1 indent
if i.lstrip()!='':
itemStr = "'" + i.lstrip() + "'"
else:
itemStr = ''
if level < count:
if first:
outString += '['*(count - level) + itemStr
first = 0
else:
outString += ',' + '['*(count - level) + itemStr
elif level > count:
outString += ']'*(level - count) + ',' + itemStr
else:
if first:
outString += itemStr
first = False
else:
outString += ',' + itemStr
level = count
if len(outString)>1:
outString = outString[:-1] + ']'
else:
outString = '[]'
output = eval(outString)
#['Test1', ['NeedHelp', ['GotStuck', ['Sometime', 'NoLuck']], 'NeedHelp2', ['StillStuck', 'GoodLuck']]]
Riffing off of this answer, if entire lines want to be retained and if those lines consist of more than just variable names, t.type == NAME can be substituted with t.type == NEWLINE, and that if-statement can append the stripped line instead of the t.string. Something like this:
from tokenize import NEWLINE, INDENT, DEDENT, tokenize
def parse(file):
stack = [[]]
lastindent = len(stack)
def push_new_list():
stack[-1].append([])
stack.append(stack[-1][-1])
return len(stack)
for t in tokenize(file.readline):
if t.type == NEWLINE:
if lastindent != len(stack):
stack.pop()
lastindent = push_new_list()
stack[-1].append(t.line.strip()) # add entire line to current list
elif t.type == INDENT:
lastindent = push_new_list()
elif t.type == DEDENT:
stack.pop()
return stack[-1]
Otherwise, the lines get split on any token, where a token includes spaces, parentheses, brackets, etc.
I have a project where the user pulls up a specific URL where the values for Dept, Queue, and Day change by what hyperlink they choose. For example, they would click on a hyperlink and the URL would be something like:
http://www.myworkplace.com/UserPlatform/User/Process.aspx?Dept=DeptOne&Queue=18&Day=0
The next hyperlink could be:
http://www.myworkplace.com/UserPlatform/User/Process.aspx?Dept=DeptFive&Queue=13&Day=9.
I would like to use InStr to find Dept, Queue, and Day within the URL, then set their values to variables, such as UDept, UQueue, and UDay. Depending upon these values, the user can then copy a specific ID number that can only be found on the URL with these values. The end result would be a search for the URL:
http://www.myworkplace.com/UserPlatform/User/Process.aspx?Dept=UDept&Queue=UQueue&Day=UDay
Here's my code so far:
Option Explicit
Dim objIE, objShell, objShellWindows
Dim strIDNum, strURL, strWindow, strURLFound, WShell, i
strURL = "http://www.myworkplace.com/UserPlatform/User/Process.aspx?Dept=DeptOne&Queue=18&Day=0"
strWindow = "Workflow Process"
Set objIE = CreateObject("InternetExplorer.Application")
Set objShell = CreateObject("Shell.Application")
Set objShellWindows = objShell.Windows
Set WShell = CreateObject("WScript.Shell")
strURLFound = False
'To fix item not found error
For Each objIE in objShellWindows
Next
For i = 0 to objShellWindows.Count - 1
Set objIE = objShellWindows.Item(i)
On Error Resume Next
If InStr(Ucase(objShellWindows.Item(i).LocationURL), Ucase(strURL)) Then
If InStr(Ucase(objShellWindows.Item(i).FullName), "IEXPLORE.EXE") Then
If Err.Number = 0 Then
If InStr(objShellWindows.Item(i).document.title, (strWindow)) Then
strURLFound = True
Exit For
End If
End If
End If
End If
Next
WShell.AppActivate strWindow
WScript.Sleep 300
strIDNum = objIE.document.getElementByID("ID_PlaceHolder").value
Thank you in advance to anyone who can help me with this.
Have you considered using a regular expression?
dim re, s
dim matches
s = "http://www.myworkplace.com/UserPlatform/User/Process.aspx?Dept=DeptFive&Queue=13&Day=9"
Set re = new RegExp
re.Pattern = ".*?Dept=(\w+)&Queue=(\d+)&Day=(\d+)$"
Set matches = re.Execute(s)
Dim uDept, uQueue, uDay
uDept = matches(0).submatches(0)
uQueue = matches(0).submatches(1)
uDay = matches(0).submatches(2)
Msgbox join(array("uDept = " & uDept, "uQueue = " & uQueue , "uDay = " & uDay), vbNewLine)
' Output:
' uDept = DeptFive
' uQueue = 13
' uDay = 9
To replace you can also use a Regular Expression:
Set re = new RegExp
s = "http://www.myworkplace.com/UserPlatform/User/Process.aspx?Dept=DeptFive&Queue=13&Day=9"
newDept = "DeptFourtyTwo"
newQueue = 404
newDay = 12
re.Pattern = "(Dept=)\w+"
newUrl = re.Replace(s, "$1" & newDept)
re.Pattern = "(Queue=)\d+"
newUrl = re.Replace(newUrl, "$1" & newQueue)
re.Pattern = "(Day=)\d+"
newUrl = re.Replace(newUrl, "$1" & newDay)
msgbox newUrl
' output:
' http://www.myworkplace.com/UserPlatform/User/Process.aspx?Dept=DeptFourtyTwo&Queue=404&Day=12
' Alternatively you can replace everything at once if the order and presence of
' parameters is guaranteed:
re.Pattern = "(Dept=)\w+(&Queue=)\d+(&Day=)\d+"
MsgBox re.Replace(s, "$1DeptFourtyTwo$2404$312")
This only using Instr and Mid Function's
s="http://www.myworkplace.com/UserPlatform/User/Process.aspx?Dept=DeptFive&Queue=13&Day=9"
a = InStr(s, "?") 'We get the value until ?
d1 = Mid(s, a)
c1 = InStr(d1, "=")
c2 = InStr(d1, "&")
d2 = Mid(d1, c2 + 1)
d3 = Mid(d1, c1 + 1, (c2 - c1) - 1) 'value of Dept is d3
c3 = InStr(d2, "=")
c4 = InStr(d2, "&")
d5 = Mid(d2, c4 + 1)
d4 = Mid(d2, c3 + 1, (c4 - c3) - 1) 'value of Queue is d4
c6 = InStr(d5, "=")
d6 = Mid(d5, c6 + 1) ' Value of Day is d6
Hope this helps