Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix line 71 IndexError at Windows #39

Closed
wants to merge 2 commits into from
Closed

fix line 71 IndexError at Windows #39

wants to merge 2 commits into from

Conversation

sunrabbit123
Copy link

I used this app
but I get this bug

Traceback (most recent call last):
  File "C:\Users\user\AppData\Roaming\Python\Python39\Scripts\wifi-password-script.py", line 33, in <module>
    sys.exit(load_entry_point('wifi-password==1.0.7', 'console_scripts', 'wifi-password')())
  File "C:\Users\user\AppData\Roaming\Python\Python39\site-packages\wifi_password\wifi_password.py", line 116, in main
    password = get_password(args.ssid)
  File "C:\Users\user\AppData\Roaming\Python\Python39\site-packages\wifi_password\wifi_password.py", line 76, in get_password
    password = re.findall(r"Key Content\s+:\s(.*)", password)[0]
IndexError: list index out of range

That's why I added this.

def get_password(ssid):
    if ssid == "":
        print_error("SSID is not defined")

    if sys.platform == "darwin":
        password = run_command(f"security find-generic-password -l \"{ssid}\" -D 'AirPort network password' -w")
        password = password.replace("\n", "")

    elif sys.platform == "linux":
        # Check if the user is running with super user privilages
        if os.geteuid() != 0:
            password = run_command(f"sudo nmcli -s -g 802-11-wireless-security.psk connection show '{ssid}'")
        else:
            password = run_command(f"nmcli -s -g 802-11-wireless-security.psk connection show '{ssid}'")

        password = password.replace("\n", "")

    elif sys.platform == "win32":
        password = run_command(f"netsh wlan show profile name=\"{ssid}\" key=clear | findstr Key").replace("\r", "")
        try:
            password = re.findall(r"Key Content\s+:\s(.*)", password)[0]
        except IndexError:
            password = ""
    if password == "":
        print_error("Could not find password")

    return password

@sdushantha
Copy link
Owner

Thank you for bringing this up.

Do you know why this error is happening? Is it because the WiFi does not have a password?

@sunrabbit123
Copy link
Author

In my case, the OS language is not English.

I'm from korea, So I use Korean.

Engilsh case:

Key Content : !@#!$!@#

Korean Case:

키 콘텐츠 : !@#!@#

Different languages display differently.
It looks good to get OS language and classify it automatically.
Korean example is here

@sdushantha
Copy link
Owner

This is interesting. Does #25 happen to fix the issue you are facing?

@sunrabbit123
Copy link
Author

Probably.

However, it is difficult for me to understand the solution of #25.

Can I ask you to explain the code of #25?
What does LANG=C cause?

@sdushantha
Copy link
Owner

@sunrabbit123 The 'LANG' environment variable indicates the language/locale and encoding, where "C" is the default language setting, English.

@sunrabbit123
Copy link
Author

sunrabbit123 commented Feb 8, 2021

I understand. Thank you.
Let's think about LANG=C.

But I think the solution is to make a big dictionary to get keywords that fit your language.

Examples are below.

keyword_dict = {
    "en_US" : ["Key", "Key Contents"],
    "ko_KR" : ["키" : "키 콘텐츠"]
    .
    .
    .
}
key = keyword_dict["en_US"]

@sdushantha
Copy link
Owner

Thank you for your suggestion.

Could you try replacing the current run_function function with the one below and let me know if that worked for you?

def run_command(command):
    env = os.environ.copy()
    env["LANG"] = "C"
    output, _ = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, shell=True).communicate()
    return output.decode("utf-8").rstrip('\r\n')

I think setting the locale would be a much better approach at fixing this issue as less code is needed to do so.

@sunrabbit123
Copy link
Author

sunrabbit123 commented Feb 8, 2021

LANG=C didn't work for me.

The ploblem is netsh wlan show profiles name=SSID key=clear | findstr Key

netsh wlan show interfaces | findstr SSID
    SSID                   : SK_WiFiGIGA42C0
    BSSID                  : 00:23:aa:dc:42:c3

netsh wlan show profiles name="SK_WiFiGIGA42C0" key=clear | findstr 키
    보안 키           : 있음
    키 콘텐츠            : password

but

netsh wlan show profiles name="SK_WiFiGIGA42C0" key=clear | findstr Key

ERROR: Could not find password

and

We also found additional problems.
When decoding with utf-8, the following error appears.

Traceback (most recent call last):
  File "C:\Users\user\AppData\Roaming\Python\Python39\Scripts\wifi-password-script.py", line 33, in <module>
    sys.exit(load_entry_point('wifi-password==1.0.7', 'console_scripts', 'wifi-password')())
  File "C:\Users\user\AppData\Roaming\Python\Python39\site-packages\wifi_password\wifi_password.py", line 124, in main
    password = get_password(args.ssid)
  File "C:\Users\user\AppData\Roaming\Python\Python39\site-packages\wifi_password\wifi_password.py", line 78, in get_password
    password = run_command(f"netsh wlan show profiles name=\"{ssid}\" key=clear | findstr 키").replace("\r", "")
  File "C:\Users\user\AppData\Roaming\Python\Python39\site-packages\wifi_password\wifi_password.py", line 23, in run_command
    return output.decode("utf-8").rstrip('\r\n')
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xba in position 4: invalid start byte

But the solution is simple.
You can decode it as follows:

return output.decode("euc-kr")

@sdushantha
Copy link
Owner

This means we would have to have a translation of the word "Key" in every language and then decode the output based on the system's language, right?

I'll have to think about this because having a dictionary of the translation of all languages seems to be a waste of lines of code in my opinion. But if there is no other option, we'll have to stick with that then.

@sunrabbit123
Copy link
Author

I think so.

However, rather than supporting all languages, I think it is better to provide basic support for English, but to provide opportunities for contributors to participate.

You can know your own language with a simple Python script.

The code is as follows:

import locale
lang, _ = locale.getdefaultlocale()
print(lang)

Windows supports approximately 106 languages.
I don't think it's a big file even if it's symmetrical with the key.

I think it would be good to use json.

Thank you for reviewing my opinion.
But I wish I had a better way.

Because my method is not very efficient.

@sdushantha
Copy link
Owner

Could you try this instead?

def run_command(command):
    env = os.environ.copy()
    env["LC_ALL"] = "C"
    output, _ = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, shell=True).communicate()
    return output.decode("utf-8").rstrip('\r\n')

Does this work? The change I made is env["LC_ALL"] = "C". According to this AskUbuntu post, it should set the output of the commands to English.

@sunrabbit123
Copy link
Author

sunrabbit123 commented Feb 10, 2021

Unfortunately, it doesn't work on Windows.

However, I will find a way to change the output of the command to English

@sdushantha
Copy link
Owner

Most of the command line tools are translated to local languages, but from time to time user may want the output of command line tools to be in English. For Windows 7 system on languages such as East Asian (Japanese, Korean, Chinese Simplify and Traditional), Russian and Greek there is a trick to do that.

  1. Start console window on localized version of Windows 7.

  2. Change code page in console window to English by typing chcp 437 and press Enter.

  3. Run your application and you should see output is in English.

Source: https://channel9.msdn.com/Blogs/witastre/How-to-see-command-line-tools-output-in-English-on-East-Asian-Russian-and-Greek-language-of-Windows-

@sunrabbit123
Copy link
Author

run_command("chcp 437")

It works very sexy.
However, it is a problem that the page is updated.
This 'chcp' command cannot be modified because it has only one language code.

I think you can put this code at the beginning of the main function.

def main():
    run_command("chcp 437")
    .
    .
    .
    .

@celianvdb
Copy link
Contributor

Could you try this instead?

def run_command(command):
    env = os.environ.copy()
    env["LC_ALL"] = "C"
    output, _ = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, shell=True).communicate()
    return output.decode("utf-8").rstrip('\r\n')

Does this work? The change I made is env["LC_ALL"] = "C". According to this AskUbuntu post, it should set the output of the commands to English.

After created the env variable you need to apply it for your subprocess. To do that you have to add env as parameters in subprocess.Popen() methods by adding env=env. So it becomes :

 def run_command(command):
     env = os.environ.copy()
     env["LC_ALL"] = "C"
     output, _ = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, shell=True, env=env).communicate()
     return output.decode("utf-8").rstrip('\r\n')

@celianvdb
Copy link
Contributor

run_command("chcp 437")

It works very sexy.
However, it is a problem that the page is updated.
This 'chcp' command cannot be modified because it has only one language code.

I think you can put this code at the beginning of the main function.

def main():
    run_command("chcp 437")
    .
    .
    .
    .

I don't think that's a good idea because chcp doesn't exist on linux, by doing that, wifi-password will crash/throw an error on linux.

@sdushantha
Copy link
Owner

@celianvdb

I don't think that's a good idea because chcp doesn't exist on linux, by doing that, wifi-password will crash/throw an error on Linux.

I agree with you, it is better to put it in the areas where Windows commands get executed. The only reason why I said to put it under the main function was for testing purposes.

@sdushantha
Copy link
Owner

The language issue has been fixed in #45

@sdushantha sdushantha closed this Feb 13, 2021
@sunrabbit123 sunrabbit123 deleted the patch-1 branch February 15, 2021 12:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants