photon
2/1/2017 - 11:12 AM

IPFS wrapper to keep a hash record for the command of ipfs add

IPFS wrapper to keep a hash record for the command of ipfs add

#!/usr/bin/python

# IPFS wrapper, to keep a hash record at the base direcotry after IPFS added one single file or single dir. 
# The record file is named as .ipf
# If the same file is added to ipfs twice or more, the same ipfs output are recorded twice or more
# Works at least for linux python 2.7. It may also work on other OS platforms.

# Usage: 
# ipfs_wrapper_4add-0.1.py add path/to/single_file_or_dir [ -some_arg ... ]
# less path/to/.ipf

# todo:
# remove duplicated records
# extend to any multiple files and folders

# License: MIT
# Ver: 0.1

import sys
import os
import os.path
import subprocess
from datetime import datetime

IPFS = 'ipfs'
RECORD_FILE_SUFFIX = '.ipf'
NO_WRITE_FILE = ''

def getIpfPath(args):
    filtered = filter(
                   lambda x: not ( x.startswith('-') or 'add' == x ),
                   args[1:] 
               ) 
    filteredArgs = list(filtered)
    # It's OK here if IPFS adds only one single file or single dir
    if len(filteredArgs) > 0:
        addedPath = filteredArgs[0]
    else:
        return NO_WRITE_FILE

    pathPair = os.path.split(addedPath)
    emptyItemCount = sum(1 for i in pathPair if '' == i)
    ifmap = {0: pathPair[0], 1: os.getcwd(), 2: ''}
    ipfBase = ifmap[emptyItemCount]
    if '' == ipfBase:
        return NO_WRITE_FILE 
    if not os.access(ipfBase, os.W_OK):
        print "Unwritable base path: " + ipfBase + '\n'
        return NO_WRITE_FILE
    
    ipfPath = os.path.join(ipfBase, RECORD_FILE_SUFFIX)
    print "ipfPath: " +  ipfPath
    return ipfPath

# Wrapper for subprocess.Popen 
def popen(cmd):
    return subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)

def writeFile(stdout, ipfPath):
    def writeflush(f):
        f.write(newRecord)
        f.flush()
        os.fsync(f.fileno())
    oldRecord = ''
    newRecord = stdout + str(datetime.now()) + '\n'
    isExisted = os.path.isfile(ipfPath)
    isWritable = os.access(ipfPath, os.W_OK)
    if isExisted and not isWritable:
        print "Unwritable .ipf file: " + ipfPath
    if isExisted and isWritable:
        with open(ipfPath, 'r+') as f:
            oldRecord = f.read()
            newRecord = newRecord + oldRecord
            f.seek(0)
            writeflush(f)
    if not isExisted:
        with open(ipfPath, 'w+') as f:
            writeflush(f)

def doCmd(args):
    argStr = ''
    if len(args) > 1:
        argStr = ' '.join(args[1:]) 
    cmd = "%s %s" % (IPFS, argStr)
    print "cmd: " + cmd + '\n\n'
    stdout = popen(cmd).communicate()[0]
    sys.stdout.flush()
    print stdout
    ipfPath = NO_WRITE_FILE
    if len(args) > 1: 
        ipfPath = getIpfPath(args) 
    if NO_WRITE_FILE != ipfPath:
        writeFile(stdout, ipfPath) 

def main():
    doCmd(sys.argv) 

main()