Python - getting SerialNumber of usb-devices with pyUsb in windows - python

I'm trying to create a list of alll usb mass storage devices with their VendorIf, the ProductId and the SerialNumber.
Therefore I use the pyUsb module and run the following program.
import sys
import usb
import usb.core
import usb.util
devs = usb.core.find(find_all=True)
nCount=0
for dev in devs:
try:
for cfg in dev:
intf = usb.util.find_descriptor(cfg,bInterfaceClass=0x8)
if intf is not None:
nCount += 1
try:
sys.stdout.write("USB device " + usb.util.get_string(dev,dev.iProduct,None) + '\n')
except:
sys.stdout.write("USB device " + str(nCount) + '\n')
sys.stdout.write("------" + '\n')
sys.stdout.write("VendorId = " + hex(dev.idVendor) + '\n')
sys.stdout.write("ProductId = " + hex(dev.idProduct) + '\n')
if not dev.iSerialNumber == 0:
sys.stdout.write("SerialNbr = " + usb.util.get_string(dev,dev.iSerialNumber,None) + '\n')
else:
sys.stdout.write("SerialNbr = none" + '\n')
sys.stdout.write('\n')
except usb.core.USBError:
pass
In generally the script works. Depending on the device I get outputs like this:
USB device USB DISK
-------
VendorId = 0x90c
ProductId = 0x2000
SerialNbr = none
But with various devices I get the following error:
File
"C:\Users\UerXy\AppData\Local\Programs\Python\Python39\lib\site-packages\usb\backend\libusb1.py",
line 600, in _check
raise NotImplementedError(_strerror(ret)) NotImplementedError: Operation not supported or unimplemented on this platform
When debugging the code, the error occures when it tries to read the string descriptor using the function usb.util.get_string()
I read somewhere, that the function is dependant on the driver.
Is this true? Isn't it possible to read the serial number of any given usb-device without taking care of the used usb-driver?
How can this error be solved and the descriptors be read from every device?

You can use the following code to get the information of all connected drives (flash memory and hdd).
import os
os.system('echo list volume > Ravi.txt')
path1 = os.path.join(os.getcwd(),"Ravi.txt")
os.system('diskpart /s '+path1+' > logfile.txt')
path2 = os.path.join(os.getcwd(),"logfile.txt")
Str = open(path2).read()
Str = Str.split('\n')
matching = [s for s in Str if "Removable" in s]
for i in matching:
i = ' '.join(i.split())
i = i.split(" ")
print(i)
import subprocess
serials = subprocess.check_output('wmic diskdrive get SerialNumber').decode().split('\n')[1:]
serials = [s.strip() for s in serials if s.strip()]
After running this code, two txt files will be created in the current location, in which the desired information is written

Related

PyUSB communication with Raspberry Pi and custom temp / humidity sensor

I have:
USB HID raw temp/humidity sensor
raspberry Pi B
I want:
python to get data from USB sensor on the PI
With the help of several different web pages and some answers on this site, I have found the device, I can show the interface details and send an array and get one data point, but then the device is busy and times out. Why would it only send one reading and then require replugging to get another data point? My first thought was maybe it is the device, but the device works just fine on my windows box. Is my python code wrong?
The USB device sends 16 bit data on interrupt IN endpoint #1 and receives data on interrupt OUT endpoint 2 (because that is how I wrote the firmware).
Python code:
#!/usr/bin/env python
import usb
import sys
dev = usb.core.find(idVendor=0x1dfd, idProduct=0x0006)
if not dev:
raise IOError('Device not found')
else:
# dev.set_configuration()
cfg = dev.get_active_configuration();
# cfg = [(0,0)]
print ("Device located")
print ('configuration ' + str(cfg));
for configuration in dev:
for interface in configuration:
ifnum = interface.bInterfaceNumber
if not dev.is_kernel_driver_active(ifnum):
continue
try:
print "detach %s: %s" % (dev, ifnum)
dev.detach_kernel_driver(ifnum)
reattach = True
renum = ifnum
except usb.core.USBError, e:
pass
dev.set_configuration()
interface_number = 0
alternate_setting = usb.control.get_interface(dev,interface_number)
intf = usb.util.find_descriptor(cfg, bInterfaceNumber = interface_number,bAlternateSetting = alternate_setting)
epO = usb.util.find_descriptor(
intf,
custom_match = \
lambda f: \
usb.util.endpoint_direction(f.bEndpointAddress) == \
usb.util.ENDPOINT_OUT
)
epI = usb.util.find_descriptor(
intf,
custom_match = \
lambda f: \
usb.util.endpoint_direction(f.bEndpointAddress) == \
usb.util.ENDPOINT_IN
)
# write the data
print('epI length ' + str(epI.bLength))
print('ep desc type ' + str(epI.bDescriptorType))
print('ep address ' + str(epI.bEndpointAddress))
print('ep xfer type ' + str(epI.bmAttributes))
# print('ep synch type ' + str(epI.bmAttributes[1]))
# print('ep Use type ' + str(epI.bmAttributes[2]))
print('ep max packet ' + str(epI.wMaxPacketSize))
print('ep interval ' + str(epI.bInterval))
print('epO length ' + str(epO.bLength))
print('ep desc type ' + str(epO.bDescriptorType))
print('ep address ' + str(epO.bEndpointAddress))
print('ep xfer type ' + str(epO.bmAttributes))
# print('ep synch type ' + str(epO.bmAttributes[1]))
# print('ep Use type ' + str(epO.bmAttributes[2]))
print('ep max packet ' + str(epO.wMaxPacketSize))
print('ep interval ' + str(epO.bInterval))
print('dev length ' + str(dev.bLength))
print('dev num configs ' + str(dev.bNumConfigurations))
print('dev class ' + str(dev.bDeviceClass))
assert epO is not None
assert epI is not None
msg = '2234567890123456' #first character is the command
print('writing to USB ->' + msg)
print(str(dev))
# dev.write(epO, msg, 100)
epO.write(msg)
print('reading from USB...')
ret = epI.read(16)
# ret = dev.read(2,len(msg),100) # device timeout is 50 ms,
sret = ''.join([chr(x) for x in ret])
print(sret)
# This is needed to release interface, otherwise attach_kernel_driver fails
# due to "Resource busy"
usb.util.dispose_resources(dev)
# It may raise USBError if there's e.g. no kernel driver loads
if reattach:
print('Reattaching Kernel Driver')
dev.attach_kernel_driver(renum)
and here is the response when executed on the PI:
Device located
configuration <usb.core.Configuration object at 0xb6a6e6d0>
detach <usb.core.Device object at 0xb6a6e750>: 0
epI length 7
ep desc type 5
ep address 129
ep xfer type 3
ep max packet 16
ep interval 50
epO length 7
ep desc type 5
ep address 2
ep xfer type 3
ep max packet 16
ep interval 50
dev length 18
dev num configs 1
dev class 0
writing to USB ->
<usb.core.Device object at 0xb6a6e750>
2234567890123456
reading from USB...
227.45,51.0 ## The first response has this after the last line above
## the second try gives this response instead:
Traceback (most recent call last):
File "./t8.py", line 78, in <module>
ret = epI.read(16)
File "/usr/local/lib/python2.7/dist-packages/usb/core.py", line 300, in read
return self.device.read(self.bEndpointAddress, size, self.interface, timeout)
File "/usr/local/lib/python2.7/dist-packages/usb/core.py", line 670, in read
self.__get_timeout(timeout)
File "/usr/local/lib/python2.7/dist-packages/usb/backend/libusb1.py", line 798, in intr_read
timeout)
File "/usr/local/lib/python2.7/dist-packages/usb/backend/libusb1.py", line 889, in __read
_check(retval)
File "/usr/local/lib/python2.7/dist-packages/usb/backend/libusb1.py", line 571, in _check
raise USBError(_str_error[ret], ret, _libusb_errno[ret])
usb.core.USBError: [Errno 110] Operation timed out
I searched and found that I can check the linux messages for USB with this command:
grep usb /var/log/messages
and I found this message:
Nov 3 02:16:06 raspberrypi kernel: [123725.144960] usb 1-1.3: usbfs: process 10698 (python) did not claim interface 0 before use
I added the reattach code and that went away. I searched and found that others had the issue and it might be pyUSB. I updated to the b2 release. Now the device print command gives a full HID report printout when the print(dev) command is given. Very nice, but the original problem of the device timeout remains and it is not looking like it has to do with a claimed interface.
Any insight on how I can prevent the timeout so the device can give more than one set of data?
Thanks for your help.

How do I use Python to retrieve Registry values?

I have written this code so far;
from _winreg import *
def val2addr(val):
addr = ''
for ch in val:
addr += '%02x '% ord(ch)
addr = addr.strip(' ').replace(' ', ':')[0:17]
return addr
def printNets():
net = "SOFTWARE\Microsoft\Windows NT\CurrentVersion"+\
"\NetworkList\Signatures\Unmanaged"
key = OpenKey(HKEY_LOCAL_MACHINE, net)
print '\n[*] Networks You Have Joined.'
for i in range(100):
try:
guid = EnumKey(key, i)
netKey = OpenKey(key, str(guid))
(n, addr, t) = EnumValue(netKey, 5)
(n, name, t) = EnumValue(netKey, 4)
macAddr = val2addr(addr)
netName = str(name)
print '[+] ' + netName + ' ' + macAddr
CloseKey(netKey)
except:
break
def main():
printNets()
if __name__ == "_main_":
main()
This script returns the MAC addresses and network names of all the WiFi networks you have joined.
It returns values from
Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows >NT\CurrentVersion\NetworkList\Signatures\Unmanaged\
I am on Windows 8.1 and I have checked through Regedit.exe to make sure this is the correct location for the info I am retrieving.
When I run this code it says "WindowsError: [Error 2] The system cannot find the file specified"
So what is it I am doing wrong?
P.S I am on Python 2.7.9
Full Traceback
Traceback (most recent call last):
File "<pyshell#11>", line 1, in <module>
printNets()
File "C:/Users/Nathaniel/Desktop/MacAddr Meta-Reader.py", line 13, in printNets
key = OpenKey(HKEY_LOCAL_MACHINE, net)
WindowsError: [Error 2] The system cannot find the file specified
You're probably using 32-bit Python on 64-bit Windows. In this case opening HKLM\SOFTWARE gets redirected to HKLM\SOFTWARE\Wow6432Node. You have to specify otherwise if you want the 64-bit key. For example:
key = OpenKey(HKEY_LOCAL_MACHINE, net, 0,
KEY_READ | KEY_WOW64_64KEY)
Note that for subkeys opened relative to this key object, it isn't strictly necessary to specify KEY_WOW64_64KEY.
I ported your code to run in both Python 2 and 3, added iterators, and eliminated the hard-coded range and index values. Maybe you'll find it helpful:
from __future__ import print_function
import itertools
try:
from winreg import *
except ImportError: # Python 2
from _winreg import *
KEY_READ_64 = KEY_READ | KEY_WOW64_64KEY
ERROR_NO_MORE_ITEMS = 259
def iterkeys(key):
for i in itertools.count():
try:
yield EnumKey(key, i)
except OSError as e:
if e.winerror == ERROR_NO_MORE_ITEMS:
break
raise
def itervalues(key):
for i in itertools.count():
try:
yield EnumValue(key, i)
except OSError as e:
if e.winerror == ERROR_NO_MORE_ITEMS:
break
raise
def val2addr(val):
return ':'.join('%02x' % b for b in bytearray(val))
NET_UNMANAGED = (r"SOFTWARE\Microsoft\Windows NT\CurrentVersion"
r"\NetworkList\Signatures\Unmanaged")
def printNets(keystr=NET_UNMANAGED):
key = OpenKey(HKEY_LOCAL_MACHINE, keystr, 0, KEY_READ_64)
print('\n[*] Networks You Have Joined.')
for guid in iterkeys(key):
netKey = OpenKey(key, guid)
netName, macAddr = '', ''
for name, data, rtype in itervalues(netKey):
if name == 'FirstNetwork':
netName = data
elif name == 'DefaultGatewayMac':
macAddr = val2addr(data)
if netName:
print('[+]', netName, macAddr)
CloseKey(netKey)
CloseKey(key)
The key's security descriptor only allows access to administrators and the netprofm service, as shown below. So you either need to run the script from an elevated command prompt or use a technique to have the script autoelevate.
C:\>set NT=HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion
C:\>accesschk -qldk "%NT%\NetworkList\Signatures\Unmanaged"
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\
NetworkList\Signatures\Unmanaged
DESCRIPTOR FLAGS:
[SE_DACL_PRESENT]
[SE_DACL_PROTECTED]
OWNER: BUILTIN\Administrators
[0] ACCESS_ALLOWED_ACE_TYPE: NT SERVICE\netprofm
[CONTAINER_INHERIT_ACE]
[INHERITED_ACE]
KEY_QUERY_VALUE
KEY_CREATE_LINK
KEY_CREATE_SUB_KEY
KEY_ENUMERATE_SUB_KEYS
KEY_NOTIFY
KEY_SET_VALUE
READ_CONTROL
DELETE
[1] ACCESS_ALLOWED_ACE_TYPE: BUILTIN\Administrators
[CONTAINER_INHERIT_ACE]
[INHERITED_ACE]
KEY_ALL_ACCESS
C:\>sc qdescription netprofm
[SC] QueryServiceConfig2 SUCCESS
SERVICE_NAME: netprofm
DESCRIPTION: Identifies the networks to which the computer has
connected, collects and stores properties for these networks,
and notifies applications when these properties change.
Do you have administrator privileges? I tried walking down the tree with "reg query" to make sure that I didn't have a spelling problem and when I got to "NetworkList" I got an Access denied error. I changed to administrator privileges and everything was fine.
reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList
ERROR: Access is denied.

How do you print network history using _winreg in Python?

I'm trying to print out the network history saved in the Windows Registry and am running into a snag.
I have two functions. One to convert the binary text, and the second to get the actual data.
Here is what I have:
def val2addr(val):
addr = ""
for ch in val:
addr += ("%02x "% ord(ch))
addr = addr.strip(" ").replace(" ", ":")[0:17]
return addr
def printNets():
net = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Signatures\Unmanaged"
key = OpenKey(HKEY_LOCAL_MACHINE, net)
print key
print '\n[*] Networks You have Joined.'
for i in range(100):
try:
guid = EnumKey(key, i)
netKey = OpenKey(key, str(guid))
(n, addr, t) = EnumValue(netKey, 5)
macAddr = val2addr(addr)
netName = str(name)
print '[+] ' + netName + ' ' + macAddr
CloseKey(netKey)
except:
break
I believe the error is in this guid value:
for i in range(100):
try:
guid = EnumKey(key, i)
netKey = OpenKey(key, str(guid))
(n, addr, t) = EnumValue(netKey, 5)
When I run the "try" subcode by itself it throws up a:
[ERROR 259] no more data available
pointing to the guid value.
I think that is where I am stuck. I'm having trouble finding the error because it just gets thrown to the except code, and thus not giving me any feedback.
Please help!!!
EDIT: From what I am digging up it may be due to running 32bit Python on a 64bit system. Still digging though.
When I came across the 32/64 bit problem I got round it by using code similar to this
import winreg
HKLM =winreg.HKEY_LOCAL_MACHINE
bb = r"SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Signatures\Unmanaged"
abc = winreg.OpenKeyEx(HKLM, bb,0,(winreg.KEY_WOW64_64KEY + winreg.KEY_ALL_ACCESS))
efg = winreg.EnumKey(abc,0)
z = winreg.OpenKeyEx(abc,str(efg))
q = winreg.QueryValueEx(z,"Description")[0]
print (q)
q = winreg.QueryValueEx(z,"DefaultGatewayMac")[0]
print (q)
Hope this helps pointing you in the right direction

Get fat32 attributes with python

How i can get fat32 attributes (like archived, hidden...) in linux without spawning a new process with fatattr utility call ? May be there is python binding for it or for linux/fs functions (fat_ioctl_get_attributes, http://www.cs.fsu.edu/~baker/devices/lxr/http/source/linux/fs/fat/file.c). Or maybe it can be done with python-xattr ?
As you can see in the function name, the kernel function fat_ioctl_get_attributes is called from userspace via an ioctl, and I'm not aware of any other binding. Therefore, you can simply read the attributes by calling ioctl yourself, like this:
import array
import fcntl
import os
FAT_IOCTL_GET_ATTRIBUTES = 0x80047210
FATATTR_BITS = 'rhsvda67'
def get_fat_attrs(fn):
fd = os.open(fn, os.O_RDONLY)
try:
buf = array.array('L', [0])
try:
fcntl.ioctl(fd, FAT_IOCTL_GET_ATTRIBUTES, buf, True)
except IOError as ioe:
if ioe.errno == 25: # Not a FAT volume
return None
else:
raise
return buf[0]
finally:
os.close(fd)
if __name__ == '__main__':
import sys
for fn in sys.argv[1:]:
attrv = get_fat_attrs(fn)
if attrv is None:
print(fn + ': Not on a FAT volume')
continue
s = ''.join((fb if (1 << idx) & attrv else ' ')
for idx,fb in enumerate(FATATTR_BITS))
print(fn + ': ' + s)

Can Django apps be called from a locally runing daemon / python script

I am new to the python language, so please bear with me. Also English isn't my native language so sorry for any misspelled words.
I have a question about updating a Django app from a daemon that runs locally on my server. I have a server setup which has 8 hot-swappable bays. Users can plug-in there hard disk(s) into the server and, after the server has detected that a new hard disk is plugged-in, it starts copying the contents of the hard disk to a location on the network. The current setup displays information about the process on an LCD screen.
The current setup works fine but I need to change it in a way that the whole process is displayed on a website (since this is more user friendly). So I need to display to the user when a disk is inserted into the server, the progress of the copy task etc.
My idea it to create a Django app that gets updated when a task in process is completed, but I can't seem to find any information about updating a Django app from a locally running daemon. It this even possible? Or is Django not the right way to go? Any ideas are welcome.
Below is my script used to copy content of disk to a location on the network. Hopefully it give some more information about what I doing/tying to do.
Many thanks in advance!
Script:
#!/usr/bin/env python
import os
import sys
import glob
import re
import time
import datetime
import pyudev
import thread
import Queue
import gobject
import getopt
from pyudev import Context
from subprocess import Popen, PIPE
from subprocess import check_call
from lcdproc.server import Server
from pyudev.glib import GUDevMonitorObserver
from gobject import MainLoop
from threading import Thread
#used to show progress info
from progressbar import ProgressBar, Percentage, Bar, RotatingMarker, ETA, FileTransferSpeed
# used to set up screens
lcd = Server("localhost", 13666, debug=False)
screens = []
widgets = []
#Used for threading
disk_work_queue = Queue.Queue()
# used to store remote nfs folders
remote_dirs = ['/mnt/nfs/', '/mnt/nfs1/', '/mnt/nfs2/']
#Foldername on remote server (NFS Share name)
REMOTE_NFS_SHARE = ''
# a process that runs infinity, it starts disk processing
# functions.
class ProcessThread(Thread):
def __init__(self):
Thread.__init__(self)
def run(self):
while 1:
try:
disk_to_be_processed = disk_work_queue.get(block=False)
set_widget_text(disk_to_be_processed[1], "Removed from queue..", "info", "on")
process_disk(disk_to_be_processed[0], disk_to_be_processed[1])
except Queue.Empty:
time.sleep(10)
set_main_widget_text("Please insert disks ")
# used to set message on the lcdscreen, message are set by disk
def set_widget_text(host, message, priority, blacklight):
if host == "host4":
screen_disk1 = screens[1]
screen_disk1.clear()
screen_disk1.set_priority(priority)
screen_disk1.set_backlight(blacklight)
widgets[1].set_text(str(message))
elif host == "host5":
screen_disk2 = screens[2]
screen_disk2.clear()
screen_disk2.set_priority(priority)
screen_disk2.set_backlight(blacklight)
widgets[2].set_text(str(message))
elif host == "host6":
screen_disk3 = screens[3]
screen_disk3.clear()
screen_disk3.set_priority(priority)
screen_disk3.set_backlight(blacklight)
widgets[3].set_text(str(message))
elif host == "host7":
screen_disk4 = screens[4]
screen_disk4.clear()
screen_disk4.set_priority(priority)
screen_disk4.set_backlight(blacklight)
widgets[4].set_text(str(message))
# used to set a message for all hosts
def set_widget_text_all(hosts, message, priority, blacklight):
for host in hosts:
set_widget_text(host, message, priority, blacklight)
def set_main_widget_text(message):
screen_disk1 = screens[0]
screen_disk1.clear()
screen_disk1.set_priority("info")
screen_disk1.set_backlight("on")
widgets[0].set_text(str(message))
# mounts, find logs files and copy image files to destionation
def process_disk(disk, host):
datadisk = mount_disk(disk, host)
source = datadisk + "/images"
set_widget_text(host, "Processing, hold on ", "info", "on")
cases = find_log(source)
upload(source, cases, host)
time.sleep(5)
umount_disk(host)
set_widget_text(host, "Disk can be removed", "info", "blink")
time.sleep(10)
# search the datadisk for logfiles containing information
# about cases and images
def find_log(src):
inf = ""
case = []
for root,dirs,files in os.walk(src):
for f in files:
if f.endswith(".log"):
log = open(os.path.join(root,f), 'r')
lines = log.readlines()[2:5]
for l in lines:
inf += re.sub("\n","",l[11:]) + ":"
log.close()
print inf
case.append(inf)
inf = ""
return case
def get_directory_size(dir):
dir_size = 0
for(path, dirs, files) in os.walk(dir):
for file in files:
filename = os.path.join(path, file)
dir_size+=os.path.getsize(filename)
return dir_size
# copies the image files to the destination location, dc3dd is used
# to copy the files in a forensicly correct way.
def upload(src, cases, host):
remotedir = ''
while len(cases) > 0:
count = 0
nfs_share_found = False
case = cases.pop()
onderzoek = case.split(':')[0];
#verwijder de _ uit de naam van het object
object = case.split(':')[1];
#image = case.split(':')[2];
localdir = src + '/' + onderzoek + '/' + object +'/'
total_files = len(os.listdir(localdir))
folder_size = get_directory_size(localdir)
for d in remote_dirs:
if os.path.exists(d + onderzoek + '/B/' + object.replace('_',' ') + '/Images/'):
nfs_share_found = True
remotedir = d + onderzoek + '/B/' + object.replace('_', ' ') + '/Images/'
break
if nfs_share_found == False:
set_widget_text(host, " Onderzoek onbekend ", "info", "flash")
time.sleep(30)
return
for root,dirs,files in os.walk(localdir):
for uploadfile in files:
currentfile = os.path.join(root, uploadfile)
file_size = os.stat(currentfile).st_size
copy_imagefile(currentfile, onderzoek, object, remotedir)
count += 1
percentage = int(count*file_size*100/folder_size)
message = onderzoek + " Obj: " + object + "..%d%%" % percentage
set_widget_text(host, message, "info", "on")
set_widget_text(host, " Copy Succesfull! ", "info", "flash")
# the actualy function to copy the files, using dc3dd
def copy_imagefile(currentfile, onderzoek, object, remotedir):
currentfilename = os.path.basename(currentfile)
dc3dd = Popen(["dc3dd", "if=" + currentfile, "hash=md5", "log=/tmp/"+ onderzoek + "_" + object + ".log", "hof=" + remotedir + currentfilename,"verb=on", "nwspc=on"],stdin=PIPE,stdout=PIPE, stderr=PIPE)
dc3dd_stdout = dc3dd.communicate()[1]
awk = Popen([r"awk", "NR==13 { print $1 }"],stdin=PIPE, stdout=PIPE)
awk_stdin = awk.communicate(dc3dd_stdout)[0]
output = awk_stdin.rstrip('\n')
if output == "[ok]":
return False
else:
return True
# when a disk gets inserted into the machine this function is called to prepare the disk
# for later use.
def device_added_callback(self, device):
position = device.sys_path.find('host')
host = device.sys_path[(position):(position+5)]
set_widget_text(host, " New disk inserted! ", "info", "on")
time.sleep(2)
disk = "/dev/" + device.sys_path[-3:] + "1"
disk_work_queue.put((disk, host))
set_widget_text(host, " Placed in queue... ", "info", "on")
# gets called when the disk is removed form the machine
def device_removed_callback(self, device):
position = device.sys_path.find('host')
host = device.sys_path[(position):(position+5)]
#message = 'Slot %s : Please remove drive' % host[4:]
set_widget_text(host, " Replace disk ", "info", "on")
# mounts the partition on the datadisk
def mount_disk(disk, host):
#device = "/dev/" + disk + "1"
mount_point = "/mnt/" + host
if not os.path.exists(mount_point):
os.mkdir(mount_point)
cmd = ['mount', '-o', 'ro,noexec,noatime,nosuid', str(disk), str(mount_point)]
check_call(cmd)
set_widget_text(host, " Disk mounted ", "info", "on")
return mount_point
# umounts the partition datadisk
def umount_disk(host):
mount_point = "/mnt/" + host
cmd = ['umount', str(mount_point)]
check_call(cmd)
os.removedirs(mount_point)
def build_screens():
screen_main = lcd.add_screen("MAIN")
screen_main.set_heartbeat("off")
screen_main.set_duration(3)
screen_main.set_priority("background")
widget0_1 = screen_main.add_string_widget("screen0Widget1", " Welcome to AFFC ", x=1, y=1)
widget0_2 = screen_main.add_string_widget("screen0Widget2", "Please insert disks ", x=1, y=2)
widgets.append(widget0_2)
screens.append(screen_main)
screen_disk1 = lcd.add_screen("DISK1")
screen_disk1.set_heartbeat("off")
screen_disk1.set_duration(3)
screen_disk1.clear()
widget_disk1_1 = screen_disk1.add_string_widget("disk1Widget1", " Slot 1 ", x=1, y=1)
widget_disk1_2 = screen_disk1.add_string_widget("disk1Widget2", " Please insert disk ", x=1, y=2)
widgets.append(widget_disk1_2)
screens.append(screen_disk1)
screen_disk2 = lcd.add_screen("DISK2")
screen_disk2.set_heartbeat("off")
screen_disk2.set_duration(3)
widget_disk2_1 = screen_disk2.add_string_widget("disk2Widget1", " Slot 2 ", x=1, y=1)
widget_disk2_2 = screen_disk2.add_string_widget("disk2Widget2", " Please insert disk ", x=1, y=2)
widgets.append(widget_disk2_2)
screens.append(screen_disk2)
screen_disk3 = lcd.add_screen("DISK3")
screen_disk3.set_heartbeat("off")
screen_disk3.set_duration(3)
widget_disk3_1 = screen_disk3.add_string_widget("disk3Widget1", " Slot 3 ", x=1, y=1)
widget_disk3_2 = screen_disk3.add_string_widget("disk3Widget2", " Please insert disk ", x=1, y=2)
widgets.append(widget_disk3_2)
screens.append(screen_disk3)
screen_disk4 = lcd.add_screen("DISK4")
screen_disk4.set_heartbeat("off")
screen_disk4.set_duration(3)
widget_disk4_1 = screen_disk4.add_string_widget("disk4Widget1", " Slot 4 ", x=1, y=1)
widget_disk4_2 = screen_disk4.add_string_widget("disk4Widget2", " Please insert disk ", x=1, y=2)
widgets.append(widget_disk4_2)
screens.append(screen_disk4)
def restart_program():
"""Restarts the current program.
Note: this function does not return. Any cleanup action (like
saving data) must be done before calling this function."""
python = sys.executable
os.execl(python, python, * sys.argv)
def main():
try:
opts, args = getopt.getopt(sys.argv[1:], "hd:v", ["help", "destination="])
except getopt.GetoptError, err:
# print help information and exit:
print str(err) # will print something like "option -a not recognized"
usage()
sys.exit(2)
verbose = False
for o, a in opts:
if o == "-v":
verbose = True
elif o in ("-h", "--help"):
usage()
sys.exit()
elif o in ("-d", "--destination"):
REMOTE_NFS_SHARE = a
else:
assert False, "unhandled option"
lcd.start_session()
build_screens()
#t = Thread(target=loop_disks_process())
#t.start();
context = pyudev.Context()
monitor = pyudev.Monitor.from_netlink(context)
observer = GUDevMonitorObserver(monitor)
observer.connect('device-added', device_added_callback)
observer.connect('device-removed', device_removed_callback)
monitor.filter_by(subsystem='block', device_type='disk')
monitor.enable_receiving()
mainloop = MainLoop()
gobject.threads_init()
t = ProcessThread()
t.start()
mainloop.run()
raw_input("Hit <enter>")
t.running = False
t.join()
if __name__ == "__main__":
try:
main()
except Exception, e:
restart_program()
Sorry, much too much code to read there.
I'm not sure what you mean by "updating" a Django app. Do you mean adding some data into the database? This is easy to do, either by getting your script to write directly into the DB, or by using something like a custom Django management command which can use the ORM.
Take a look at Django Piston. You can implement a RESTful API on your django app and call those apis from your demon. I use it on one of my project in which some worker processes need to communicate to frontend django apps periodically.
It could be done like this:
Daemon shares its disk information/copy progress using some inter-process communication method like simple text file or some memory objects;
Django view could then read this info and display it to the user;
Or daemon could call Django management command (#Daniel Roseman) and that command will then update app DB to represent current state.
Consider using something like Memcached as a shared area to store the state of the drives.
As the drives are added or removed, the daemon should write those changes to Memcached, and on each page load the Django web app should read the state from Memcached. You could use a management command and a SQL database, but that seems like too many moving parts for such simple problem: you're only storing a handful boolean flags.
You might even try a micro-framework like Flask instead of Django, to reduce the complexity even more.

Categories