Generalized Desktop directory - python

Simple enough, off of my last question, I am trying to make a directory change to a players desktop or file that is similar for all, as in C:\\Users\\USERNAME\\Desktop\\Tester File but the how would I make it so that USERNAME is the username of the person's computer? I tried using %USERNAME% but I don't really know how to do that, and it didn't work, and anyway the % gave an error message (I cannot remember the message, I think it was syntax error)
I also tried using ~, but it proved to be ineffective, but it may be due to my lack of experience.
EDIT
I solved this issue, thanks to some very great help from #pstatix so thank you.
By using user = getpass.getuser() I was able to do something like 'C:\Users' + user + '\Documents' it made this all user friendly! Thanks!

Have you tried the getpass module? getpass documentation here.
import getpass
usr = getpass.getuser()
print usr
Edit: For user specified example
You may also be interested in using the os module? os documentation here.
import os
usr = os.getlogin()
path = os.path.join('..', 'Users', usr, 'Desktop', 'Tester File')
os.chdir(path)
Using os.environ for environment variables may also prove useful. os.environ documentation here For example:
import os
def getUserName():
# set possible environment variables
for name in ('LOGNAME', 'USER', 'LNAME', 'USERNAME'):
usr = os.environ.get(name)
if user:
return usr #return the variable
if __name__ == '__main__':
usr = getUserName()
# do remainder below

Related

How to check OS variables and use them with same name as Python variable from a list

hopefully i can explain right what i am trying to do. I want to check if variables giving from a list, exists in OS, if so, use the same OS variable name and value in python.
This is how am i doing it right now but i think it is a lot of code and if want more os variables i would be bigger. So what could be a good starting to do this smarter and more efficient?
OS (linux) variables
export WEB_URL="https://google.com"
export WEB_USERNAME="Foo"
export WEB_PASSWORD="Bar"
# Check os env variables
if "WEB_URL" in os.environ:
web_url = os.environ.get("WEB_URL")
else:
logger.error("No URL os env find please check")
if "WEB_USERNAME" in os.environ:
web_username = os.environ.get("WEB_USERNAME")
else:
logger.error("No USERNAME os env find please check")
if "WEB_PASSWORD" in os.environ:
web_password = os.environ.get("WEB_PASSWORD")
else:
logger.error("No PASSWORD os env find please check")
must be somthing like this to start with?
os_variables = ["WEB_URL", "WEB_USERNAME", "WEB_PASSWORD"]
for var in os_variables:
if var in os.environ:
print(var.lower(), "=", os.environ.get(f"{var}"))
result:
web_url = https://google.com
web_username = Foo
web_password = Bar
so what is printed here above should literally be the variable, just to show what i mean
as a compromise I finally came up with this as a solution
env_variables = ('WEB_URL', 'WEB_USERNAME', 'WEB_PASSWORD')
def check_env(var):
for var in env_variables:
if var in os.environ:
if os.environ[var] == "":
logging.error(f'{var} is empty, please set a value')
sys.exit()
else:
logging.error(
f'{var} does not exist, please setup this env variable')
sys.exit()
check_env(env_variables)
If I understand your problem correctly you will need to make use of eval() and exec(). Maybe something along those lines:
exec(str(eval(var.lower(), "=", "'", os.environ.get(f"{var}")"'")))
Evaluating first should give you something like web_url = 'https://google.com'. If this is turned into a string it can be executed, but be careful with global and local variables in this case.

Dictionary reference keeps throwing an unsolved reference

I am building a mock terminal-like program using python, and am trying to build a login system for it.
My directory setup, after going through multiple revisions, eventually came out to look like this:
pythonapp-harlker/
__init__.py
loginCheck.py
main.py
userlist.py
__init__.py is empty, and main.py's main code chunk looks like this:
from loginCheck import *
loginFunc = Login()
loginFunc.login()
if loginFunc.login().checkPass == True:
print("Welcome %s!" % (username))
Importing loginCheck returns no error, so naturally, I looked at loginCheck.py.
import sys, platform, importlib
import hashlib
from userlist import *
class Login:
def login(self):
username = input("Username: ")
password = input("Password: ")
password = str.encode(password)
password = str(hashlib.md5(password).hexdigest())
if username in users:
userPassAndIndex = users.get(username)
if password == userPassAndIndex[0]:
checkPass = True
value = userPassAndIndex[1]
else:
self.login()
else:
self.login()
Looking at a debugger, it keeps telling me that loginCheck.py is unable to import a dictionary from userlist.py.
userlist.py
users = {
'localAdmin10': ["086e717a4524329da24ab80e0a9255e2", 0],
'orlovm': ["505ec2b430fa182974ae44ede95ca180", 1],
'testUser10': ["90e611f269e75ec5c86694f900e7c594", 2],
'torradiRemote': ["0b841ebf6393adac25950a215aecc3d1", 3],
}
Additionally, while running the python code (from main.py), the code seems unable to detect if the input username and passwords are correct.
I've looked at tons of stackOverflow pages and external sources but I'm at a kind of "programmer's block" now.
Your code runs fine on Python 3+, and breaks on Python 2.7, let me explain why:
the input function you want to use with Python 2.7 is raw_input, not input. The input function in Python 2.7, evaluates the user input as a Python expression, so in your case, can't find it and send an exception
raw_input was renamed input starting Python 3.0
So to sum it up, you just have to pick the right function depending on which version of Python you'd like to use. raw_inputfor Python 2.7, input for Python 3.

Storing the secrets (passwords) in a separate file

What's the simplest way to store the application secrets (passwords, access tokens) for a Python script? I thought it'd be a *.yml file like in Ruby but surprisingly I found that it wasn't the case. So what is it then? What are the most simplest solutions?
I want to put them in a separate file because that way I'll be able not to push that file to a github repository.
I think storing credentials inside another *py file is your safest bet. Then just import it. Example would look like this
config.py
username = "xy"
password = "abcd"
main.py
import config
login(config.username, config.password)
I was dealing exactly the same question and actually ended up with the same solution as kecer suggested. Since I need to use it in dozens of scripts, I've created own library. Let me share this solution with you.
credlib.py -- universal library to handle credentials
class credential:
def __init__(self, hostname, username, password):
self.hostname = hostname
self.username = username
self.password = password
mycredentials.py -- my local file to store all credentials
from credlib import credential
sys_prod = credential("srv01", "user", "pass")
sys_stg = credential("srv02", "user", "pass")
sys_db = credential("db01", "userdb", "passdb")
mysystemlib.py -- this is a general library to access my system (both new credential system and legacy is supported)
from credlib import credential
def system_login(*args): # this is new function definition
#def system_login(hostname, username, password): # this was previous function definition
if len(args) == 1 and isinstance(args[0], credential):
hostname = args[0].hostname
username = args[0].username
password = args[0].password
elif len(args) == 3:
hostname = args[0]
username = args[1]
password = args[2]
else:
raise ValueError('Invalid arguments')
do_login(hostname, username, password) # this is original system login call
main.py -- main script that combines credentials and system libs
from mycredentials import sys_stg, sys_db
import mysystemlib
...
mysystemlib.system_login(sys_stg)
Please note that the legacy hostname/username/password way still works so it does not affect old scripts:
mysystemlib.system_login("srv02", "user", "pass")
This has a lot benefits:
same credential system across all our python scripts
files with passwords are separated (files can have more strict permissions)
files are not stored in our git repositories (excluded via .gitignore) so that our python scripts/libs can be shared with others without exposing credentials (everyone defines their own credentials in their local files)
if a password needs to be changed, we do it at a single place only
Personally I prefer to use yaml files, with the pyyaml library.
Documentation here: https://pyyaml.org/wiki/PyYAMLDocumentation
Creating a .gitignore rule is very quick and painless and there is zero chances of making a mistake. You can added the rule with echo on Linux / UNIX like system with:
echo -e '*.yaml\n*.yml' >> .gitignore
Below is an example of retrieving the settings from a settings .yaml file in the same folder / location of the reader.
Code Snippets:
#!/usr/bin/env python3
import yaml
from pathlib import Path
def get_settings():
full_file_path = Path(__file__).parent.joinpath('settings.yaml')
with open(full_file_path) as settings:
settings_data = yaml.load(settings, Loader=yaml.Loader)
return settings_data

Importing and storing the data from a Python file

How do I import a Python file and use the user input later?
For example:
#mainprogram
from folder import startup
name
#startup
name = input('Choose your name')
What I want is to use the startup program to input the name, then be able to use the name later in the main program.
You can access that variable via startup.name later in your code.
name will be in startup.name. You can use dir(startup) to see it.
Or, as an alternate solution:
# Assuming from the names that 'folder' is a folder and 'startup' is a Python script
from folder.startup import *
now you can just use name without the startup. in front of it.
I think is better do your code in classes and functions.
I suggest you to do:
class Startup(object):
#staticmethod
def getName():
name = ""
try:
name = input("Put your name: ")
print('Name took.')
return True
except:
"Can't get name."
return False
>> import startup
>> Startup.getName()

Python hashlib.md5 and ejabberd

I am using a python script as an external auth option in ejabberd 2.1.6.
I wanted to start encrypting the clear text passwords that come across in the auth verification, so that they are not being stored in plain text in the backend database. When I add the following code to my python script and restart ejabberd, it hangs:
import hashlib
clear = "barfoo"
salt = "foobar"
hash = hashlib.md5( salt + clear ).hexdigest()
Does hashlib require specific priviledges to run?
When I run it as a normal user (ejabberd) it works without issue. When the python script is run within the external auth of ejabberd it hangs.
I've attempted to have it write out the 'hash' to a file and it never gets there ... if i run it as the 'ejabberd' user, it writes out to file fine.
I've tried to find information about restrictions for using this library on ubuntu without any success. Any ideas?
-sd
** 22.02.2011: Here is the full script adapted from https://git.process-one.net/ejabberd/mainline/blobs/raw/2.1.x/doc/dev.html#htoc8 :
#!/usr/bin/python
import sys
from struct import *
import hashlib
def from_ejabberd():
input_length = sys.stdin.read(2)
(size,) = unpack('>h', input_length)
return sys.stdin.read(size).split(':')
def to_ejabberd(bool):
answer = 0
if bool:
answer = 1
token = pack('>hh', 2, answer)
sys.stdout.write(token)
sys.stdout.flush()
def auth(username, server, password):
clear = "barfoo"
salt = "foobar"
hash = hashlib.md5( salt + clear ).hexdigest()
if (password == hash): return True
else: return False
def isuser(username, server):
return True
def setpass(username, server, password):
return True
while True:
data = from_ejabberd()
success = False
if data[0] == "auth":
success = auth(data[1], data[2], data[3])
elif data[0] == "isuser":
success = isuser(data[1], data[2])
elif data[0] == "setpass":
success = setpass(data[1], data[2], data[3])
to_ejabberd(success)
I have been messing with the same problem. I Can't really track down the problem with openssl binings in _hashlib. Whatever the problem is, i will have to patch python distribution sources. Not really an feasible solution. So i ended up using a pycrypto wrapper for the crypto functions which don't block in this case.
pip install pycrypto
from Crypto.Hash import MD5
m = MD5.new()
m.update("%s%s" % (salt ,clear))
h.hexdigest()
I looked into the hashlib source and while it does not seem to require too much, it does import .so files as modules and one of them hits openssl. It all looks pretty safe but if ejabberd tries to fence itself against calls to 3rd party code (or if you have SELinux or something else to that effect running), stuff can conceivably get weird. I got this in a REPL:
>>> import _md5
>>> _md5.__file__
'/usr/lib/python2.7/lib-dynload/_md5module.so'
Try this on your box and then try putting
_md5 = imp.load_dynamic('_md5', '/usr/lib/python2.7/lib-dynload/_md5module.so')
Or just
import _md5
(with the appropriate path updated to yours) in your code before the offending line and with some trace statement afterwards. Try the same with _hashlib instead of _md5 (hashlib defaults to _hashlib which wraps openssl, but if it doesn't load or doesn't have the needed hash it falls back to _md5, _sha etc.). If it's not the imports that fail/hang then you can try calling _md5.new(salt + clear) and _hashlib.openssl_md5(salt + clear) and see if it's one of them.
If it is the import at fault, then possibly a similar problem was tackled here
I don't know ejabberd, so I can't relate their solution to your problem, unfortunately.
I do have to say it, though: in all python implementations I know, = instead of == in a condition would raise a SyntaxError and that's that - the program would never even enter the main while loop.
hashlib does not require anything special. What means hangs? Where does it hang? Use pdb.set_trace() to step trough the code or use 'strace' or 'ltrace' to investigate API calls.
Try to use logging module, it can help you to watch input and output data, also check scripts permissions, let executing by user which is ejabberd, or for debug just set chmod 777 external.py.

Categories

Resources