Python 2.7.9 subprocess convert check_output to dictionary (volumio) - python-2.7

I've been searching a long time, but I can't find an answer.
I'm making a script for volumio on my Raspberry Pi
In the terminal, when I type
volumio status
I get exactly
{
"status": "pause",
"position": 0,
"title": "Boom Boom",
"artist": "France Gall",
"album": "Francegall Longbox",
"albumart": "/albumart?cacheid=614&web=France%20Gall/Francegall%20Longbox/extralarge&path=%2FUSB&metadata=false",
"uri": "/Boom Boom.flac",
"trackType": "flac",
"seek": 21192,
"duration": 138,
"samplerate": "44.1 KHz",
"bitdepth": "16 bit",
"channels": 2,
"random": true,
"repeat": null,
"repeatSingle": false,
"consume": false,
"volume": 100,
"mute": false,
"stream": "flac",
"updatedb": false,
"volatile": false,
"service": "mpd"
}
In python, I would like to store this in a dictionary
since it already has the right formatting, I thought that assigning it to a variable will make it a dictionnary right away as follows:
import subprocess, shlex
cmd = "volumio status | sed -e 's/true/True/g' -e 's/false/False/g' -e 's/null/False/g'"
cmd = shlex.split(cmd)
status = subprocess.check_output(cmd)
print status["volume"]
If what I thought was true I would get "100". Instead, I get this error :
File "return.py", line 7, in <module>
print status["volume"]
TypeError: string indices must be integers, not str
this means "status" is stored as a string. Does anybody know how I can make it a dictionary?
dict() doesn't make it, i get :
ValueError: dictionary update sequence element #0 has length 1; 2 is required

Victory! I was able to make my code work with eval()
import subprocess
status = subprocess.check_output("volumio status | sed -e 's/true/True/g' -e 's/false/False/g' -e 's/null/False/g'", shell=True)
status = eval(status)
print status["volume"]
it returns 100

Related

awk (or sed/grep) to get occurrences of substring

I have a json string in a bash variable, which is something like this:
{
"items": [
{
"foo": null,
"timestamp": 1553703000,
"bar": 123
},
{
"foo": null,
"timestamp": 1553703200,
"bar": 456
},
{
"foo": null,
"timestamp": 1553703400,
"bar": 789
}
]
}
I want to know how many of those timestamps are after a given datetime, so if I have 1553703100 it'll return 2.
(Bonus imaginary points if you can get me just that number!)
As a step towards that, I want to get just the matches of "timestamp": \d+, in the string so that I can loop through them in a bash script.
I've used sed and grep a bit, but never used awk, and from my reading it seems like that might be the better match for the task.
Other info:
- The json is already pretty-printed, as above, so the timestamps would always be on separate lines.
- This is to run in Cygwin, so I have awk/gawk, sed, and grep/egrep, but probably not others.
- Could be any number of timestamps in the json.
You didn't provide the expected output so it's a guess but is this what you're trying to do?
$ echo "$var" | jq '.items[].timestamp'
1553703000
1553703200
1553703400
or maybe:
$ echo "$var" | jq '.items[].timestamp | select(. > 1553703100)'
1553703200
1553703400
or:
$ echo "$var" | jq '[.items[].timestamp | select(. > 1553703100)] | length'
2
WARNING: I'm just learning jq so there may be better ways to do the above!
edit: The second approach listed below has serious problems that were very helpfully outlined by #EdMorton. I've elected to keep the old code for educational purposes.
Avoided substr() and caught null string i:
$ awk -v dt=1553703100 '
/timestamp/ && $2+0>dt {i++}
END {print i+0}
' <<< "$var"
2
WARNING: PROBLEMATIC CODE
Here I used substr(string, index, [characters]) to trim the comma off your second field. The /timestamp/ regex is not complex; it could be improved if your json became more intricate.
$ awk -v dt=1553703100 '
/timestamp/ && substr($2, 0, length($2)) > dt {i++}
END {print i}
' <<< "$var"
2
You can also implement quickly a python solution:
input:
$ cat data.json
{
"items": [
{
"foo": null,
"timestamp": 1553703000,
"bar": 123
},
{
"foo": null,
"timestamp": 1553703200,
"bar": 456
},
{
"foo": null,
"timestamp": 1553703400,
"bar": 789
}
]
}
code:
$ cat extract_value2.py
import json
tLimit = 1553703100
with open('data.json') as f:
data = json.load(f)
print([t['timestamp'] for t in data["items"] if t['timestamp'] > tLimit])
output:
$ python extract_value2.py
[1553703200, 1553703400]
count code:
$ cat extract_value2.py
import json
tLimit = 1553703100
with open('data.json') as f:
data = json.load(f)
print(len([t['timestamp'] for t in data["items"] if t['timestamp'] > tLimit]))
output:
$ python extract_value2.py
2

Newman / Postman - Cannot replace value for a key in the Environment JSON, from command line

I'm new to both Postman and Newman.
I have created my simple test which uses the Environment Variables JSON for some properties values.
It runs fine when the value for this key is hardcoded in the environment.json but it's failing if I'm trying to pass/replace the value for the key from the command-line.
I do not have global variable json, and if possible, prefer not to use it.
Here is my command-line:
newman run "C:\Users\Automation\Postman\postman_autotest.json" --folder "AUTO" --global-var "client_secret=XXXX" --environment "C:\Users\Automation\Postman\postman_environment.json"
This value is essential for the API to work/connect, thus I'm getting 400 error back.
here is this key in the environment.json
{
"id": "673a4256-f5a1-7497-75aa-9e47b1dbad4a",
"name": "Postman Env Vars",
"values": [
{
"key": "client_secret",
"value": "",
"description": {
"content": "",
"type": "text/plain"
},
"enabled": true
}
],
"_postman_variable_scope": "environment",
"_postman_exported_at": "2019-04-03T20:31:04.829Z",
"_postman_exported_using": "Postman/6.7.4"
}
Just a thought... You can use a wrapper powershell script to replace the key at runtime then delete the file.
[CmdletBinding()]
Param (
[Parameter(Mandatory)]
[string]$Secret
)
$envFile = "C:\Users\Automation\Postman\postman_environment.json"
$envFileWithKey = "C:\Users\Automation\Postman\postman_environment_w_key.json"
$json = Get-Content $envFile -Raw | ConvertFrom-Json
$json.values[0].key = $Secret
ConvertTo-Json $json -Depth 10 | Out-File $envFileWithKey -Force
newman run "C:\Users\Automation\Postman\postman_autotest.json" --folder "AUTO" --environment $envFileWithKey
Remove-Item -Path $envFileWithKey
Then just:
.\RunAutomation.ps1 -Secret "this_is_a_secret_sshhhhhh"

Batch in postman

I need post data from postman, but I have results limit (200 result for one query). I have 45 000 results. In this case, I need run query a lot of times for getting all data.
"select" : "(**)", "start": 0, "count": 200,
"select" : "(**)", "start": 201, "count": 401,
"select" : "(**)", "start": 402, "count": 502,
"select" : "(**)", "start": 503, "count": 603
Do we have any ways to run query using 1000 branch for example?

BASH: Regex -> empty result

I'm using bash but I do not get a bash rematch... Every online regex check tool worked fine for this string and regex.
#!/bin/bash
set -x
regex='hd_profile_pic_url_info": {"url": "([0-9a-zA-Z._:\/\-_]*)"'
str='{"user": {"pk": 12345, "username": "dummy", "full_name": "dummy", "is_private": true, "profile_pic_url": "censored", "profile_pic_id": "censored", "is_verified": false, "has_anonymous_profile_picture": false, "media_count": 0, "follower_count": 71114, "following_count": 11111, "biography": "", "external_url": "", "usertags_count": 0, "hd_profile_pic_versions": [{"width": 320, "height": 320, "url": "censored"}, {"width": 640, "height": 640, "url": "censored"}], "hd_profile_pic_url_info": {"url": "https://scontent-frt3-2.cdninstagram.com/vp/censored/censored_a.jpg", "width": 930, "height": 930}, "has_highlight_reels": false, "auto_expand_chaining": false}, "status": "ok"}'
[[ $str =~ $regex ]] && echo ${BASH_REMATCH}
Parsing json with bash it's not a good idea, as others said, jq is the right tool for the job.
Having said that, I think
regex='hd_profile_pic_url_info": {"url": "[0-9a-zA-Z._:\/_-]*"'
would work. Notice the '-' as the last char in the set, to avoid being interpreted as a range.
You have to remove the duplicate _ at the end of your regex :
regex='"hd_profile_pic_url_info": {"url": "([0-9a-zA-Z._:\/\-]*)"'

Select a particular type of word from a text file and load it in a Variable

I am trying to use a power shell script to read the contents of a file and pick a specific type of word from it. I need to load the word that is found as a variable which I intend to use further downstream.
This is how my input file looks like:
{
"AvailabilityZone": "ap-northeast-1b",
"VolumeType": "gp2",
"VolumeId": "vol-087238f9",
"State": "creating",
"Iops": 100,
"SnapshotId": "",
"CreateTime": "2016-09-15T12:17:27.952Z",
"Size": 10
}
The specific word I would like to pick is vol-xxxxxxxx.
I used this link to write my script
How to pass a variable in the select-string of powershell
This is how I am doing it:
$Filename = "c:\reports\volume.jason"
$regex = "^[vol-][a-z0-9]{8}$"
$newvolumeid=select-string -Pattern $regex -Path $filename > C:\Reports\newVolumeid.txt
$newVolumeid
When I run this script it runs but does not give any response. Seems somehow the output of select string is not loaded into the variable $newvolumeid.
Any idea how to resolve this? Or what I am missing?
PS: The post mentioned above is about 3 years old and doesn't work hence I am reposting.
You are trying to read a property of a JSON object. Instead of using regex, you can parse the JSON and select the property using:
Get-Content 'c:\reports\volume.jason' | ConvertFrom-Json | select -ExpandProperty VolumeId
Try this
$Inpath = "E:\tests\test.txt"
$INFile = Get-Content $Inpath
$NeedsTrimming = $INFile.Split(" ") | ForEach-Object {if ($_ -like '*vol-*'){$_}}
$FirstQuote = $NeedsTrimming.IndexOf('"')
$LastQuote = $NeedsTrimming.LastIndexOf('"')
$vol = $NeedsTrimming.Substring(($FirstQuote + 1),($LastQuote - 1))
$vol