I'm trying to update windows using these commands that only work via the terminal, more specifically via the PowerShell terminal
But I'm almost getting the biggest problem and that these commands only work for the administrator and when I run the script I can't make it run automatically in the administrator terminal
`
import os
import time
cmd = "PowerShell"
class UpdateMachine:
def init(self):
self.prompt_env = "powershell"
def _generate_command(self, command: str):
os.system(f"{self.prompt_env} {command}")
def _adiminstrador(self):
self._generate_command("start-process powershell -verb runas")
time.sleep(1)
def _install_psWindwosUpdate(self):
self._generate_command("Install-Module -Name PSWindowsUpdate")
#-Scope CurrentUser
time.sleep(15)
self._generate_command("S")
time.sleep(10)
self._generate_command("S")
def _installteste(self):
self._generate_command("Set-ExecutionPolicy -ExecutionPolicy RemoteSigned")
time.sleep(15)
self._generate_command("A")
def _validate_for_updates(self):
self._generate_command("Get-WindowsUpdate")
def _installation_process(self):
self._generate_command("Install-WindowsUpdate")
time.sleep(30)
self._generate_command("A")
def _restart(self):
self._generate_command("Y")
def run(self):
self._adiminstrador()
self._install_psWindwosUpdate()
self. _validate_for_updates()
self._installation_process()
self._restart()
teste = UpdateMachine()
teste._adiminstrador()
teste._install_psWindwosUpdate
teste. _validate_for_updates()
teste._installation_process
teste._restart
`
Related
PyQt4/QProcess issues with Nuke v9...
I am trying to utilize a QProcess to run renders in Nuke at my workplace. The reason why I want to use a QProcess is because I've setup this Task Manager with the help of the community at stackoverflow, which takes a list of commands and sequentially runs it one by one, and also allows me to display an output. You can view the question I posted here:
How to update UI with output from QProcess loop without the UI freezing?
Now I am trying to basically run Nuke renders through this "Task Manager". But every time I do it just gives me an error that the QProcess is destroyed while still running. I mean I tested this with subprocess and that worked totally fine. So i am not sure why the renders are not working through QProcess.
So to do more testing I just wrote a simplified version at home. The first issue I ran into though is that apparently PyQt4 couldn't be found from Nuke's python.exe. Even though I have PyQt4 for my main Python version. However apparently there is a compatibility issue with my installed PyQt4 since my main Python version is 2.7.12, while my Nuke's python version is 2.7.3. So i thought "fine then i'll just directly install PyQt4 inside my Nuke directory". So i grabbed this link and installed this PyQt version into my Nuke directory:
http://sourceforge.net/projects/pyqt/files/PyQt4/PyQt-4.10.3/PyQt4-4.10.3-gpl-Py2.7-Qt4.8.5-x64.exe
So i run my little test and seems to be doing the same thing as it does in my workplace, where the QProcess just gets destoryed. So i thought maybe adding "waitForFinished()" would maybe do something different, but then it gives me this error that reads:
The procedure entry point ??4QString##QEAAAEAV0#$$QEAV0##Z could not be located in the dynamic link library QtCore4.dll
And gives me this error as well:
ImportError: Failed to load C:\Program Files\Nuke9.0v8\nuke-9.0.8.dll
Now at this point I can't really do any more testing at home, and my studio is closed for the holidays. So i have two questions i'd like to ask:
1) What is this error I am seeing about "procedure entry point"? It only happens when i try to call something in a QProcess instance.
2) Why is my QProcess being destroyed before the render is finished?? How come this doesn't happen with subprocess? How can I submit a Nuke render job while acheiving the same results as subprocess?
Here is my test code:
import os
import sys
import subprocess
import PyQt4
from PyQt4 import QtCore
class Task:
def __init__(self, program, args=None):
self._program = program
self._args = args or []
#property
def program(self):
return self._program
#property
def args(self):
return self._args
class SequentialManager(QtCore.QObject):
started = QtCore.pyqtSignal()
finished = QtCore.pyqtSignal()
progressChanged = QtCore.pyqtSignal(int)
dataChanged = QtCore.pyqtSignal(str)
#^ this is how we can send a signal and can declare what type
# of information we want to pass with this signal
def __init__(self, parent=None):
# super(SequentialManager, self).__init__(parent)
# QtCore.QObject.__init__(self,parent)
QtCore.QObject.__init__(self)
self._progress = 0
self._tasks = []
self._process = QtCore.QProcess(self)
self._process.setProcessChannelMode(QtCore.QProcess.MergedChannels)
self._process.finished.connect(self._on_finished)
self._process.readyReadStandardOutput.connect(self._on_readyReadStandardOutput)
def execute(self, tasks):
self._tasks = iter(tasks)
#this 'iter()' method creates an iterator object
self.started.emit()
self._progress = 0
self.progressChanged.emit(self._progress)
self._execute_next()
def _execute_next(self):
try:
task = next(self._tasks)
except StopIteration:
return False
else:
print 'starting %s' % task.args
self._process.start(task.program, task.args)
return True
def _on_finished(self):
self._process_task()
if not self._execute_next():
self.finished.emit()
def _on_readyReadStandardOutput(self):
output = self._process.readAllStandardOutput()
result = output.data().decode()
self.dataChanged.emit(result)
def _process_task(self):
self._progress += 1
self.progressChanged.emit(self._progress)
class outputLog(QtCore.QObject):
def __init__(self, parent=None, parentWindow=None):
QtCore.QObject.__init__(self)
self._manager = SequentialManager(self)
def startProcess(self, tasks):
# self._manager.progressChanged.connect(self._progressbar.setValue)
self._manager.dataChanged.connect(self.on_dataChanged)
self._manager.started.connect(self.on_started)
self._manager.finished.connect(self.on_finished)
self._manager.execute(tasks)
#QtCore.pyqtSlot()
def on_started(self):
print 'process started'
#QtCore.pyqtSlot()
def on_finished(self):
print 'finished'
#QtCore.pyqtSlot(str)
def on_dataChanged(self, message):
if message:
print message
def nukeTestRender():
import nuke
nuke.scriptOpen('D:/PC6/Documents/nukeTestRender/nukeTestRender.nk')
writeNode = None
for node in nuke.allNodes():
if node.Class() == 'Write':
writeNode = node
framesList = [1, 20, 30, 40]
fr = nuke.FrameRanges(framesList)
# nuke.execute(writeNode, fr)
for x in range(20):
print 'random'
def run():
nukePythonEXE = 'C:/Program Files/Nuke9.0v8/python.exe'
thisFile = os.path.dirname(os.path.abspath("__file__"))
print thisFile
cmd = '"%s" %s renderCheck' %(nukePythonEXE, __file__)
cmd2 = [__file__, 'renderCheck']
cmdList = [Task(nukePythonEXE, cmd2)]
# subprocess.call(cmd, stdin=None, stdout=None, stderr=None, shell=False)
taskManager = outputLog()
taskManager.startProcess(cmdList)
taskManager._manager._process.waitForFinished()
if __name__ == "__main__":
print sys.argv
if len(sys.argv) == 1:
run()
elif len(sys.argv) == 2:
nukeTestRender()
I have managed to come up with an answer, so I will write in the details below:
Basically, I was getting the error with the installed PyQt4 because it was not compatible with my version of Nuke, so it is apparently more recommended to use PySide included in Nuke. However Nuke's Python executable cannot natively find PySide, a few paths needed to be added to the sys.path:
paths = ['C:\\Program Files\\Nuke9.0v8\\lib\\site-packages,
C:\\Users\\Desktop02\\.nuke',
'C:\\Program Files\\Nuke9.0v8\\plugins',
'C:\\Program Files\\Nuke9.0v8\\pythonextensions\\site-packages\\setuptools-0.6c11-py2.6.egg',
'C:\\Program Files\\Nuke9.0v8\\pythonextensions\\site-packages\\protobuf-2.5.0-py2.6.egg',
'C:\\Program Files\\Nuke9.0v8\\pythonextensions\\site-packages',
'C:\\Program Files\\Nuke9.0v8\\plugins\\modules',
'C:\\Program Files\\Nuke9.0v8\\configs\\Python\\site-packages',
'C:\\Users\\Desktop02\\.nuke\\Python\\site-packages']
for path in paths:
sys.path.append(path)
I found the missing paths by opening up both Nuke in GUI mode and the Python executable, and comparing both sys.path to see what the Python executable was lacking.
And to answer my own main question: if I call waitForFinished(-1) on the QProcess instance, this ignores the default 30sec limit of this function... Answer came from this thread:
QProcess and shell : Destroyed while process is still running
So here is my resulting working code:
import os
import sys
import subprocess
sysArgs = sys.argv
try:
import nuke
from PySide import QtCore
except ImportError:
raise ImportError('nuke not currently importable')
class Task:
def __init__(self, program, args=None):
self._program = program
self._args = args or []
#property
def program(self):
return self._program
#property
def args(self):
return self._args
class SequentialManager(QtCore.QObject):
started = QtCore.Signal()
finished = QtCore.Signal()
progressChanged = QtCore.Signal(int)
dataChanged = QtCore.Signal(str)
#^ this is how we can send a signal and can declare what type
# of information we want to pass with this signal
def __init__(self, parent=None):
# super(SequentialManager, self).__init__(parent)
# QtCore.QObject.__init__(self,parent)
QtCore.QObject.__init__(self)
self._progress = 0
self._tasks = []
self._process = QtCore.QProcess(self)
self._process.setProcessChannelMode(QtCore.QProcess.MergedChannels)
self._process.finished.connect(self._on_finished)
self._process.readyReadStandardOutput.connect(self._on_readyReadStandardOutput)
def execute(self, tasks):
self._tasks = iter(tasks)
#this 'iter()' method creates an iterator object
self.started.emit()
self._progress = 0
self.progressChanged.emit(self._progress)
self._execute_next()
def _execute_next(self):
try:
task = next(self._tasks)
except StopIteration:
return False
else:
print 'starting %s' % task.args
self._process.start(task.program, task.args)
return True
def _on_finished(self):
self._process_task()
if not self._execute_next():
self.finished.emit()
def _on_readyReadStandardOutput(self):
output = self._process.readAllStandardOutput()
result = output.data().decode()
self.dataChanged.emit(result)
def _process_task(self):
self._progress += 1
self.progressChanged.emit(self._progress)
class outputLog(QtCore.QObject):
def __init__(self, parent=None, parentWindow=None):
QtCore.QObject.__init__(self)
self._manager = SequentialManager(self)
def startProcess(self, tasks):
# self._manager.progressChanged.connect(self._progressbar.setValue)
self._manager.dataChanged.connect(self.on_dataChanged)
self._manager.started.connect(self.on_started)
self._manager.finished.connect(self.on_finished)
self._manager.execute(tasks)
#QtCore.Slot()
def on_started(self):
print 'process started'
#QtCore.Slot()
def on_finished(self):
print 'finished'
#QtCore.Slot(str)
def on_dataChanged(self, message):
if message:
print message
def nukeTestRender():
import nuke
nuke.scriptOpen('D:/PC6/Documents/nukeTestRender/nukeTestRender.nk')
writeNode = None
for node in nuke.allNodes():
if node.Class() == 'Write':
writeNode = node
framesList = [1, 20, 30, 40]
fr = nuke.FrameRanges(framesList)
nuke.execute(writeNode, fr)
# nuke.execute(writeNode, start=1, end=285)
for x in range(20):
print 'random'
def run():
nukePythonEXE = 'C:/Program Files/Nuke9.0v8/python.exe'
thisFile = os.path.dirname(os.path.abspath("__file__"))
print thisFile
cmd = '"%s" %s renderCheck' %(nukePythonEXE, sysArgs[0])
cmd2 = [sysArgs[0], 'renderCheck']
cmdList = [Task(nukePythonEXE, cmd2)]
# subprocess.call(cmd, stdin=None, stdout=None, stderr=None, shell=False)
taskManager = outputLog()
taskManager.startProcess(cmdList)
taskManager._manager._process.waitForFinished(-1)
if __name__ == "__main__":
print sys.argv
if len(sysArgs) == 1:
run()
elif len(sysArgs) == 2:
nukeTestRender()
For whatever reason, PySide refuses to load for me without the nuke module imported first. and also theres a known error when importing nuke it deletes all sys.argv arguments so thats gotta be stored somewhere first before the nuke import...
Pycharm can run correctly my code, which print subprocess stdout one by one to qt widget (QTextBrower), but after pyinstaller to .exe, it will print all stdouts at once till the subprocess finished, that is not a expected result
I tried use flush() and stdout.close in the subprocess, still the same.
class NonBlockingStreamReader:
def __init__(self, stream):
self._s = stream
self._q = Queue()
def _populateQueue(stream, queue):
while True:
line = stream.readline()
if line:
queue.put(line)
#else:
#raise UnexpectedEndOfStream
self._t = Thread(target = _populateQueue, args = (self._s, self._q))
self._t.daemon = True
self._t.start() #start collecting lines from the stream
def readline(self, timeout=None):
try:
return self._q.get(block=timeout is not None, timeout=timeout)
except Empty:
return None
......
form = uic.loadUiType("data/GUI/GUI.ui")[0]
class Form(QtGui.QDialog, form):
def __init__(self, parent=None):
QtGui.QDialog.__init__(self, parent)
self.setupUi(self)
os.chdir("../../")
self.LogAnalyzeButton.clicked.connect(self.LogAnalyzePre)
......
def LogAnalyzePre(self):
self.Console.append("Analyzing log, please wait . . . . . . ." + "\n" )
arguments = 'python log.py %s'%(path)
self.proc = Popen(arguments, stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=True)
nbsr = NonBlockingStreamReader(self.proc.stdout)
while self.proc.poll() is None:
line = nbsr.readline(0.1)
print line
if line:
self.Console.insertPlainText(unicode(line, "utf-8"))
self.Console.moveCursor(QtGui.QTextCursor.End)
QtGui.QApplication.processEvents()
when run .exe, I can see the debug cmd window show that line's value is always None, and till the subprocess closed, the stdouts in queue are print at once
This has been proved it is a mistake that I did't put the log.py which had been added a flush() method into the same folder with .exe, so the flush() method can definitely solve this stdout output issue
In my python script I am doing bluetooth and RF communication on individual threads respectively. I want to add Rest Web Method in same script using Bottle web framework.
If I add below code, in existing python script, it wont work. How to make it work in existing script.
from bottle import Bottle, run
app = Bottle()
#app.route('/hello')
def hello():
return "Hello World!"
run(app, host='localhost', port=8080, debug = True)
It works fine on my system. Did you end up solving this? Pointing the browser to http://localhost:8080/hello shows "Hello World"
What it does not work? The output Hello world on your browser? The bluetooth application?
Did you add the run(app, host='localhost', port=8080, debug = True) call in a separate thread (this function call will block)?
For example:
import threading
import time
from bottle import Bottle, run
app = Bottle()
#app.route('/hello')
def hello():
return "Hello World!"
class MyRestServer(threading.Thread):
def __init__(self, app, host, port, debug):
self.app = app
self.host = host
self.port = port
self.debug = debug
threading.Thread.__init__(self)
def run(self):
self.server = self.app.run(
host=self.host,
port=self.port,
debug=self.debug
)
s = MyRestServer(app=app, host='localhost', port=8080, debug=True)
s.start()
# Execution continues
print 'Rest server started'
while True:
time.sleep(2)
print 'Rest server running'
Replace the while True: part with the rest of your application.
The following code is written using selenium python web driver which is run in saucelabs.I am providing the browser name,version and platform in a list,how do i do the same by providing the browser details through command line arguments? I am using py.test to execute the test cases.
import os
import sys
import httplib
import base64
import json
import new
import unittest
import sauceclient
from selenium import webdriver
from sauceclient import SauceClient
# it's best to remove the hardcoded defaults and always get these values
# from environment variables
USERNAME = os.environ.get('SAUCE_USERNAME', "ranjanprabhub")
ACCESS_KEY = os.environ.get('SAUCE_ACCESS_KEY', "ecec4dd0-d8da-49b9-b719-17e2c43d0165")
sauce = SauceClient(USERNAME, ACCESS_KEY)
browsers = [{"platform": "Mac OS X 10.9",
"browserName": "chrome",
"version": ""},
]
def on_platforms(platforms):
def decorator(base_class):
module = sys.modules[base_class.__module__].__dict__
for i, platform in enumerate(platforms):
d = dict(base_class.__dict__)
d['desired_capabilities'] = platform
name = "%s_%s" % (base_class.__name__, i + 1)
module[name] = new.classobj(name, (base_class,), d)
return decorator
#on_platforms(browsers)
class SauceSampleTest(unittest.TestCase):
def setUp(self):
self.desired_capabilities['name'] = self.id()
sauce_url = "http://%s:%s#ondemand.saucelabs.com:80/wd/hub"
self.driver = webdriver.Remote(
desired_capabilities=self.desired_capabilities,
command_executor=sauce_url % (USERNAME, ACCESS_KEY)
)
self.driver.implicitly_wait(30)
def test_sauce(self):
self.driver.get('http://saucelabs.com/test/guinea-pig')
assert "I am a page title - Sauce Labs" in self.driver.title
comments = self.driver.find_element_by_id('comments')
comments.send_keys('Hello! I am some example comments.'
' I should be in the page after submitting the form')
self.driver.find_element_by_id('submit').click()
commented = self.driver.find_element_by_id('your_comments')
assert ('Your comments: Hello! I am some example comments.'
' I should be in the page after submitting the form'
in commented.text)
body = self.driver.find_element_by_xpath('//body')
assert 'I am some other page content' not in body.text
self.driver.find_elements_by_link_text('i am a link')[0].click()
body = self.driver.find_element_by_xpath('//body')
assert 'I am some other page content' in body.text
def tearDown(self):
print("Link to your job: https://saucelabs.com/jobs/%s" % self.driver.session_id)
try:
if sys.exc_info() == (None, None, None):
sauce.jobs.update_job(self.driver.session_id, passed=True)
else:
sauce.jobs.update_job(self.driver.session_id, passed=False)
finally:
self.driver.quit()
So this is a bit complicated because you can pass an array of browsers into the #on_platforms decorator. My solution will only work for a single browser, as it looks like that's what you're doing right now.
For the current, single browser, situation -- you're looking for argparse. Here's my suggested fix:
import argparse
def setup_parser():
parser = argparse.ArgumentParser(description='Automation Testing!')
parser.add_argument('-p', '--platform', help='Platform for desired_caps', default='Mac OS X 10.9')
parser.add_argument('-b', '--browser-name', help='Browser Name for desired_caps', default='chrome')
parser.add_argument('-v', '--version', default='')
args = vars(parser.parse_args())
return args
desired_caps = setup_parser()
browsers = [desired_caps]
print browsers
But if you're looking to test multiple browsers (which I suggest you do!), you should not try and use command line arguments for the desired_caps of each individual browser. You should instead load a json config file for the browsers and the desired_caps for each one that you want Sauce to run.
Maybe have a different config file for each set of browsers, and then use command line arguments to pass in the config files you want to load.
I want to be able to visit a webpage and it will run a python function and display the progress in the webpage.
So when you visit the webpage you can see the output of the script as if you ran it from the command line.
Based on the answer here
How to continuously display python output in a webpage?
I am trying to display output from PYTHON
I am trying to use Markus Unterwaditzer's code with a python function.
import flask
import subprocess
app = flask.Flask(__name__)
def test():
print "Test"
#app.route('/yield')
def index():
def inner():
proc = subprocess.Popen(
test(),
shell=True,
stdout=subprocess.PIPE
)
while proc.poll() is None:
yield proc.stdout.readline() + '<br/>\n'
return flask.Response(inner(), mimetype='text/html') # text/html is required for most browsers to show the partial page immediately
app.run(debug=True, port=5005)
And it runs but I don't see anything in the browser.
Hi looks like you don't want to call a test function, but an actual command line process which provides output. Also create an iterable from proc.stdout.readline or something. Also you said from Python which I forgot to include that you should just pull any python code you want in a subprocess and put it in a separate file.
import flask
import subprocess
import time #You don't need this. Just included it so you can see the output stream.
app = flask.Flask(__name__)
#app.route('/yield')
def index():
def inner():
proc = subprocess.Popen(
['dmesg'], #call something with a lot of output so we can see it
shell=True,
stdout=subprocess.PIPE
)
for line in iter(proc.stdout.readline,''):
time.sleep(1) # Don't need this just shows the text streaming
yield line.rstrip() + '<br/>\n'
return flask.Response(inner(), mimetype='text/html') # text/html is required for most browsers to show th$
app.run(debug=True, port=5000, host='0.0.0.0')
Here's a solution that allows you to stream the subprocess output & load it statically after the fact using the same template (assuming that your subprocess records it's own output to a file; if it doesn't, then recording the process output to a log file is left as an exercise for the reader)
from flask import Response, escape
from yourapp import app
from subprocess import Popen, PIPE, STDOUT
SENTINEL = '------------SPLIT----------HERE---------'
VALID_ACTIONS = ('what', 'ever')
def logview(logdata):
"""Render the template used for viewing logs."""
# Probably a lot of other parameters here; this is simplified
return render_template('logview.html', logdata=logdata)
def stream(first, generator, last):
"""Preprocess output prior to streaming."""
yield first
for line in generator:
yield escape(line.decode('utf-8')) # Don't let subproc break our HTML
yield last
#app.route('/subprocess/<action>', methods=['POST'])
def perform_action(action):
"""Call subprocess and stream output directly to clients."""
if action not in VALID_ACTIONS:
abort(400)
first, _, last = logview(SENTINEL).partition(SENTINEL)
path = '/path/to/your/script.py'
proc = Popen((path,), stdout=PIPE, stderr=STDOUT)
generator = stream(first, iter(proc.stdout.readline, b''), last)
return Response(generator, mimetype='text/html')
#app.route('/subprocess/<action>', methods=['GET'])
def show_log(action):
"""Show one full log."""
if action not in VALID_ACTIONS:
abort(400)
path = '/path/to/your/logfile'
with open(path, encoding='utf-8') as data:
return logview(logdata=data.read())
This way you get a consistent template used both during the initial running of the command (via POST) and during static serving of the saved logfile after the fact.