import os from bureau import Bureau, add_command import pyudev AUDIO_FILETYPES = (".mp3", ".ogg", ".oga", ".flac", ".spx", ".opus", ".wav", ".aac", ".mka", ".m4a") PICTURE_FILETYPES = (".jpg", ".jpeg", ".png", ".gif", ".tif", ".bmp") PDF_FILETYPES = (".pdf", ".djvu", ".djv", ".ps", ".eps") class Archives(Bureau): """ The Archives is the central library resource for the storage and retreival of persistent data files. Audio, graphic and textual documents may be managed for the use of any other bureau. """ name = "Central Archives" prefix = "AR" version = 0 def __init__(self): Bureau.__init__(self) # TODO: get location of archive root storage from config self.mounts = {} # create a db to map shortcodes to folders on external drives self.dirmap = self.open_db("dirmap") def __scandir(self, dir_to_scan): """ recursive directory scan returns a tuple of lists of directory paths if any interesting media are found ([dirs_with_audio], [dirs_with_pictures], [dirs_with_pdfs]) """ dirs_with_audio = [] dirs_with_pictures = [] dirs_with_pdfs = [] for root, dirs, files in os.walk(dir_to_scan): audio_found = False pic_found = False pdf_found = False for file in files: _, file_ext = os.path.splitext(file) file_ext = file_ext.lower() if file_ext in AUDIO_FILETYPES: audio_found = True elif file_ext in PICTURE_FILETYPES: pic_found = True elif file_ext in PDF_FILETYPES: pdf_found = True if audio_found: dirs_with_audio.append(root) if pic_found: dirs_with_pictures.append(root) if pdf_found: dirs_with_pdfs.append(root) return dirs_with_audio, dirs_with_pictures, dirs_with_pdfs def _mount_and_archive(self, dev): # TODO: small print options to import stuff _, dev_base = os.path.split(dev) mountpoint = os.path.join("/media", dev_base) print("MOUNTING EXTERNAL MEDIUM: ", dev, "on", mountpoint) if len(self.mounts) < 26: mount_index = chr(65 + len(self.mounts)) else: print("WTF!? You have over 26 drives plugged in you wierdo. No more!") #TODO: handle this properly and make sure we don't overlap indices # pmount dev # path is always /media/device os.system("pmount " + str(dev)) self.mounts[mount_index] = {"dev": dev, "mount": mountpoint, "dirs": []} prn = self._get_small_printer() prn.textln("Achive has found external medium: ") prn.textln(mountpoint) prn.textln("EJECT DRIVE:") prn.soft_barcode("code128", "ARej." + mount_index, module_width=0.16) audio_dirs, pic_dirs, pdf_dirs = self.__scandir(mountpoint) # small_print list of media/directories that we can import # TODO: make short codes for each dir # TODO: make command that will import the dir for adir in audio_dirs: print("could add audio DIR", adir) prn.textln("Import Audio Folder:") prn.textln(adir) shortcode = self.dirmap.store_and_get_shortcode(adir) prn.soft_barcode("code128", "ARia." + shortcode, module_width=0.16) self.mounts[mount_index]["dirs"].append(shortcode) for pdir in pic_dirs: print("could add picture DIR", pdir) prn.textln("Import Image Folder:") prn.textln(pdir) shortcode = self.dirmap.store_and_get_shortcode(pdir) prn.soft_barcode("code128", "ARii." + shortcode, module_width=0.16) self.mounts[mount_index]["dirs"].append(shortcode) for pdir in pdf_dirs: print("could add document DIR", pdir) prn.textln("Import Document Folder:") prn.textln(pdir) shortcode = self.dirmap.store_and_get_shortcode(pdir) prn.soft_barcode("code128", "ARip." + shortcode, module_width=0.16) self.mounts[mount_index]["dirs"].append(shortcode) self._free_small_printer(prn) @add_command("ej", "Eject Drive") def unmount_device(self, data): """ Safely eject external media like USB Flash Drives or SD Cards """ device_idx, _ = data.split(".") dev = self.mounts[device_idx]["dev"] os.system("pumount " + str(dev)) # clean up the references for shortcode in self.mounts[device_idx]["dirs"]: self.dirmap.delete(shortcode) del(mounts[device_idx]) @add_command("ia", "Import Audio Folder") def import_audio(self, data): """ Import audio files from external media into the """ shortcode, _ = data.split(".") indir = self.dirmap.get(shortcode) print("Importing audio:", indir) print("NOT IMPLEMENTED YET") def run_io(self): # monitor for insert of any removable block storage devices (SD/USB) context = pyudev.Context() monitor = pyudev.Monitor.from_netlink(context) monitor.filter_by('block') for device in iter(monitor.poll, None): if ('ID_FS_TYPE' in device) and (device.action == "add"): self._mount_and_archive(device.device_node) def main(): ar = Archives() ar.run() if __name__ == "__main__": main()