I am trying to play audio file from web link but it seems not working now. These are the codes I tried:
local birdSound = audio.loadSound("www.sound.com/birds.mp3")
audio.play(birdSound)
It gives an error
You can't load in memory a remote audio file with the loadSound API because this function is just intended to load local files.
By default the file is searched for in the project folder (system.ResourceDirectory), but changing the baseDir parameter you can also look inside a different local folder.
So to play your remote audio file you should first dowload it in the system.DocumentsDirectory through the network.download API. When it is done you can load it with the loadSound, specifying the correct baseDir.
For details about the network.download API look here
Use the sniper below to download your remote file and then save it to localFilename at base dir basedir:
local xmnetwork = {
last_error = nil,
downloadHandlerInProgress = nil,
downloadHandlerFinished = nil,
downloadBeginHandler = nil,
network = require("network")
}
function xmnetwork.download(url, errorHandler,beganHandler, inProgressHandler, endedHandler, localFilename, basedir)
if( xmnetwork.network == nil) then
xmnetwork.network = require("network")
end
xmnetwork.downloadHandlerInProgress = inProgressHandler
xmnetwork.downloadHandlerFinished = endedHandler
xmnetwork.downloadBeginHandler = beganHandler
xmnetwork.errorHandler = errorHandler
local function downloadListener( event )
print("download event:" .. tostring(event))
if ( event.isError ) then
print( "Network error!" )
if( xmnetwork.errorHandler) then
xmnetwork.errorHandler(event)
end
elseif ( event.phase == "began" ) then
if ( event.bytesEstimated <= 0 ) then
print( "Download starting, size unknown" )
else
print( "Download starting, estimated size (in MB): " .. ( event.bytesEstimated /1024/1024))
end
if( xmnetwork.downloadBeginHandler) then
xmnetwork.downloadBeginHandler(event)
end
elseif ( event.phase == "progress" ) then
if(xmnetwork.downloadHandlerInProgress ) then
xmnetwork.downloadHandlerInProgress (event)
end
if ( event.bytesEstimated <= 0 ) then
print( "Download progress: " .. event.bytesTransferred )
else
print( "Download progress: " .. (event.bytesTransferred / event.bytesEstimated) * 100 .. "'%'")
-- log("xmnetwork.download", "downloading :" .. (event.bytesTransferred / event.bytesEstimated) * 100 .. "'%'")
end
elseif ( event.phase == "ended" ) then
print( "Download complete, total bytes transferred: " .. event.bytesTransferred )
if(xmnetwork.downloadHandlerFinished) then
xmnetwork.downloadHandlerFinished(event)
end
end
end
local params = {}
-- Tell network.request() that we want the "began" and "progress" events:
params.progress = "download"
-- Tell network.request() that we want the output to go to a file:
params.response = {
filename = localFilename,
baseDirectory = basedir
}
xmnetwork.network.request( url, "GET", downloadListener, params )
end
Related
I'd like to use nim to resize the default display resolution on a machine (windows 10 only), I want to basically do it via a command line call like setDisplay 1280 1024
I've seen and used the python example Resize display resolution using python with cross platform support which I can follow, but just can't translate. I just don't get how to fill in EnumDisplaySettings
import winim/lean
import strformat
var
cxScreen = GetSystemMetrics(SM_CXSCREEN)
cyScreen = GetSystemMetrics(SM_CYSCREEN)
msg = fmt"The screen is {cxScreen} pixels wide by {cyScreen} pixels high."
EnumDisplaySettings(Null,0, 0) #total type mismatch
MessageBox(0, msg, "Winim Example Screen Size", 0)
Tried checking stuff like https://cpp.hotexamples.com/fr/examples/-/-/EnumDisplaySettings/cpp-enumdisplaysettings-function-examples.html but wasn't much help, same for https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-changedisplaysettingsa
I wrote about 2% of this answer myself, and the rest came from pointystick on discord - thanks to them!
The solution is a bit lazy, but it's so fast that for most that won't matter.
With no cmd line args it will just set the display to the default recommendation, else with 2 cmd line args it can reset your display if it finds a match
import winim/lean
import os
import strutils
var modeToFind = (width: 1920, height: 1080, bitsPerPixel: 32,
refreshRate: 60)
var reset = 0
type ModeNotFoundError = object of CatchableError
proc getDisplayMode(): DEVMODEW =
## Finds the wanted screen resolution or raises a ModeNotFoundError.
var
nextMode: DWORD = 0
mode: DEVMODEW
while EnumDisplaySettings(nil, nextMode, mode) != 0:
echo $mode.dmPelsWidth & " x " & $mode.dmPelsHeight &
" x " & $mode.dmBitsPerPel &
" - " & $mode.dmDisplayFrequency
inc nextMode
if (mode.dmPelsWidth == modeToFind.width) and
(mode.dmPelsHeight == modeToFind.height):
echo "Found it!"
return mode
if(reset==1):
return mode
raise newException(ModeNotFoundError, "Cannot find wanted screen mode")
proc changeResolution(): bool =
## Actually changes the resolution. The return value indicates if it worked.
result = false
try:
let wantedMode = getDisplayMode()
result = ChangeDisplaySettings(wantedMode.unsafeAddr, 0.DWORD) == DISP_CHANGE_SUCCESSFUL
except ModeNotFoundError: discard
when isMainModule:
var
cxScreen:int32 = 0 #= GetSystemMetrics(SM_CXSCREEN)
cyScreen:int32 = 0 # = GetSystemMetrics(SM_CYSCREEN)
try:
cxScreen = (int32) parseInt(paramStr(1))
cyScreen = (int32) parseInt(paramStr(2))
modeToFind.width = cxScreen
modeToFind.height = cyScreen
except:
reset = 1
if not changeResolution():
echo "Change Resolution Failed"
My python script executes a .bat fie which in turn runs a Microsoft (MS) Access program. The MS Access app populates the DB then quits. Sometimes Access fails due a corrupt DB or whatever issue that may cause it to hang. I want to avoid this and kill the process if it runs longer than some seconds variable. Testing my script I set timeout=5 (seconds) for a process that takes at least 10 seconds. When the timeout fires it waits. It doesn’t kill the process but instead waits until the MS Access process completes (as per the subprocess.run python docs). How can I kill the MS Access app. The code works as expected for bat files that don’t call Access.
if( args.verbose ):
print( "Starting timer for " + str( alarmTime ) + " mintues" )
try:
proc = subprocess.run( [ batchFile ],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True,
shell=False,
check=True,
timeout=5 )
except subprocess.TimeoutExpired:
if( args.verbose ):
print ( "FAIL: Ran batch: ", batchFile, " and it timed out!" )
if( args.email ):
email( "FAIL: A batch script process is running longer than 15 minutes\nSomething is wrong\nquitting", mailTo )
returnStatus = returnStatus + " The following batch job timed out: " + batchFile + "\n"
dependancy[ batchFile ][ 1 ] = None
continue
dependancy[ batchFile ][ 1 ] = RunStatus( True, ( True if proc.returncode == 0 else False ) )
if( proc.returncode != 0 ):
returnStatus = returnStatus + " The following batch job failed: " + batchFile + "\n"
Here is my code with reads the input from a config file and moving files to another directory based on a condition and logs the information to a log file
import shutil
import configparser
import logging.handlers
import os
#Reading the input configuration
config = configparser.ConfigParser()
config.read("config_input.ini")
src_filepath = (config.get("Configuration Inputs","src_filepath"))
dst_filepath = (config.get("Configuration Inputs","dst_filepath"))
log_file_name = (config.get("Configuration Inputs","log_file_name"))
file_limit = int((config.get("Configuration Inputs","file_limit")))
if not os.path.exists (dst_filepath):
os.makedirs(dst_filepath)
onlyfiles_in_dst = next ( os.walk ( dst_filepath ) ) [ 2 ]
file_count_indst = len ( onlyfiles_in_dst )
onlyfiles_in_src = next ( os.walk ( src_filepath ) ) [ 2 ]
file_count_insrc = len ( onlyfiles_in_src )
def sorted_ls(src_filepath):
mtime = lambda f: os.stat(os.path.join(src_filepath, f)).st_mtime
return list(sorted(os.listdir(src_filepath), key=mtime))
move_list = sorted_ls(src_filepath)
#print (move_list)
if file_count_indst < file_limit:
for mfile in move_list:
shutil.move(src_filepath + '\\' + mfile, dst_filepath)
**#Logging everything**
logger = logging.getLogger()
logging.basicConfig(filename=log_file_name, format='%(asctime)s %(message)s', filemode='a')
logger.setLevel(logging.INFO)
logger.info('Number of files moved from source ' + str(len(move_list)))
But the problem is I want to move only the 1000 files from source to destination.
Something like
"ls -lrt| head ls -lrt | head -n 1000"
which I can not do iy as I am running this script on Windows platform.
Please suggest a proper way to do it.
Also please suggest how can I put it under a user defined class and may be can use in some other program.
Can't a simple counter be the solution?
if file_count_indst < file_limit:
count=0;
for mfile in move_list:
shutil.move(src_filepath + '\\' + mfile, dst_filepath)
count = count +1
if count==1000:
break
New to Python/Boto3, this should be an easy one but still learning :)
I have a Lambda function which creates a number of snapshots and works fine:
def create_snapshot():
volumes = ec2_client.describe_volumes(
Filters=[
{'N'...
...
for volume in volumes...
....
snap_name = 'Backup of ' + snap_desc
....
snap = ec2_client.create_snapshot(
VolumeId=vol_id,
Description=snap_desc
)
I then want to receive an email from AWS SNS to let me know which snapshots the function created, which I do using:
message = sns.publish(
TopicArn=SNSARN,
Subject=("Function executed"),
Message=("%s created" % snap_name)
)
The issue is that this creates an email for each snapshot, instead of one email listing all the snapshots. Should I create another function that calls all values produced by snap_desc, or can I send all values for snap_desc in the function? And most importantly what's the best way of doing this?
Cheers!
Scott
####################### UPDATE (Thanks #omuthu) #######################
I set an array inside and outside the loop, and put the string into the message. This produced the following being sent in one message:
The following snapshots have been created:
['vol-0e0b9a5dfb8379fc0 (Instance 1 - /dev/sda1)', 'vol-03aac6b65df64661e (Instance 4 - /dev/sda1)', 'vol-0fdde765dfg452631 (Instance 2 - /dev/sda1)', 'vol-0693a9568b11f625f (Instance 3 - /dev/sda1)', etc.
Okay got it sorted, finally!
def create_snapshot():
volumes = ec2_client.describe_volumes(
Filters=[
{'N'...
...
inst_list = []
for volume in volumes...
vol_id = volume['VolumeId']
....
snap_desc = vol_id
for name in volume['Tags']:
tag_key = name['Key']
tag_val = name['Value']
if tag_key == 'Name':
snap_desc = vol_id + ' (' + tag_val + ')'
....
....
....
if backup_mod is False or (current_hour + 10) % backup_mod != 0:
...
continue
else:
print("%s is scheduled this hour" % vol_id)
for name in volume['Tags']:
inst_tag_key = name['Key']
inst_tag_val = name['Value']
if inst_tag_key == 'Name':
inst_list.append(inst_tag_val)
snap = ec2_client.create_snapshot(
VolumeId=vol_id,
Description=snap_desc,
)
print("%s created" % snap['SnapshotId'])
msg = str("\n".join(inst_list))
if len(inst_list) != 0:
message = sns.publish(
TopicArn=SNSARN,
Subject=("Daily Lambda snapshot function complete"),
Message=("The following snapshots have been created today:\n\n" + msg + "\n")
)
print("Response: {}".format(message))
I want to stop a sound when another starts playing .
if (event.object1.myName == "obst3") then
audio.play(colsound)
I want this one to stop if the following one starts .
if (event.object1.myName == "t") then
audio.play(explosion)
Also, I need to know how to launch the sound just once ( when my objects collide with a wall, a sound pop out I need this one to be heard just once even if the player touches again the wall.
Play every audio with reference id value :
if (event.object1.myName == "obst3") then
local isChannel1Playing = audio.isChannelPlaying( 2 )
if isChannel1Playing then
audio.stop( playLaserSound2 )
playLaserSound2 = nil
end
playLaserSound1 = audio.play(colsound, { channel=1 })
end
if (event.object1.myName == "t") then
local isChannel1Playing = audio.isChannelPlaying( 1 )
if isChannel1Playing then
audio.stop( playLaserSound1 )
playLaserSound1 = nil
end
playLaserSound2 = audio.play(explosion, { channel=2 })
end