gonzopi

git clone https://git.tarina.org/gonzopi
Log | Files | Refs | README | LICENSE

gonzopiserver.py (20468B)


      1 #!/usr/bin/env python3
      2 
      3 import web
      4 import os
      5 import socket
      6 import ifaddr
      7 import sys
      8 import time
      9 import random
     10 import hashlib
     11 import configparser
     12 from pymediainfo import MediaInfo
     13 
     14 # Get path of the current dir, then use it as working directory:
     15 rundir = os.path.dirname(__file__)
     16 if rundir != '':
     17     os.chdir(rundir)
     18 
     19 urls = (
     20     '/','intro',   
     21     '/c/?', 'index',
     22     '/f/(.*)?', 'films',
     23     '/t/(.*)?', 'tree',
     24     '/p/(.*)?', 'player',
     25     '/api','api'
     26 )
     27 
     28 #--------------USB filmfolder-------------------
     29 
     30 def usbfilmfolder():
     31     usbmount = 0
     32     while True:
     33         usbconnected = os.path.ismount('/media/usb'+str(usbmount))
     34         time.sleep(0.02)
     35         if usbconnected == True:
     36             try:
     37                 os.makedirs('/media/usb'+str(usbmount)+'/gonzopifilms/')
     38             except:
     39                 pass
     40             try:
     41                 p = subprocess.check_output('stat -f -c %T /media/usb'+str(usbmount), shell=True)
     42                 filesystem = p.decode()
     43                 print('filesystem info: ' + filesystem)
     44             except:
     45                 print('Oh-no! dont know your filesystem')
     46             filmfolder = '/media/usb'+str(usbmount)+'/gonzopifilms/'
     47             return filmfolder
     48         else:
     49             usbmount = usbmount + 1
     50         if usbmount > 20:
     51             break
     52 
     53 home = os.path.expanduser('~')
     54 menuold = []
     55 vumeterold = ''
     56 #configfile = home + '/.gonzopi/config.ini'
     57 #configdir = os.path.dirname(configfile)
     58 #config = configparser.ConfigParser()
     59 #if config.read(configfile):
     60 #    filmfolder = config['USER']['filmfolder']+'/'
     61 filmfolder = '/home/pi/gonzopifilms/'
     62 real_filmfolder=filmfolder
     63 
     64 os.system("unlink static/*")
     65 #CHECK IF FILMING TO USB STORAGE
     66 filmfolderusb=usbfilmfolder()
     67 if filmfolderusb:
     68     filmfolder=filmfolderusb
     69     real_filmfolder=filmfolder
     70     # Link video directory to static dir
     71     os.system("ln -s -t static/ " + filmfolder)
     72     filmfolder='static/gonzopifilms/'
     73 else:
     74     os.system("ln -s -t static/ " + filmfolder)
     75     filmfolder='static/gonzopifilms/'
     76     #fix filmfolder root to Videos/gonzopifilms
     77 
     78 basedir = os.path.dirname(os.path.realpath(__file__))
     79 sys.path.append(basedir)
     80 
     81 films = []
     82 
     83 #NETWORKS
     84 
     85 networks=[]
     86 adapters = ifaddr.get_adapters()
     87 for adapter in adapters:
     88     print("IPs of network adapter " + adapter.nice_name)
     89     for ip in adapter.ips:
     90         if '::' not in ip.ip[0] and '127.0.0.1' != ip.ip:
     91             print(ip.ip)
     92             networks.append(ip.ip)
     93 network=networks[0]
     94 
     95 app = web.application(urls, globals())
     96 render = web.template.render('templates/', base="base")
     97 render2 = web.template.render('templates/', base="base2")
     98 web.config.debug=False
     99 os.system('rm '+basedir+'/sessions/*')
    100 store = web.session.DiskStore(basedir + '/sessions/')
    101 session = web.session.Session(app,store,initializer={'login': 0, 'user': '', 'backurl': '', 'bildsida': 0, 'cameras': [], 'reload': 0, 'randhash':'', 'menu':[]})
    102 
    103 port=55555
    104 ip='0.0.0.0'
    105 cameras=[]
    106 recording = False
    107 
    108 session.randhash = hashlib.md5(str(random.getrandbits(256)).encode('utf-8')).hexdigest()
    109 
    110 ##---------------Connection----------------------------------------------
    111 
    112 def pingtocamera(host, port, data):
    113     #print("Sending to "+host+" on port "+str(port)+" DATA:"+data)
    114     s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    115     s.settimeout(0.01)
    116     try:
    117         while True:
    118             s.connect((host, port))
    119             s.send(str.encode(data))
    120             if host not in cameras and host not in networks:
    121                 session.cameras.append(host)
    122                 print("Found camera! "+host)
    123             print("Sent to server..")
    124             break
    125     except:
    126         ('did not connect')
    127     s.close()
    128 
    129 def sendtocamera(host, port, data):
    130     print("Sending to "+host+" on port "+str(port)+" DATA:"+data)
    131     s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    132     s.settimeout(0.1)
    133     try:
    134         while True:
    135             s.connect((host, port))
    136             s.send(str.encode(data))
    137             print("Sent to server..")
    138             break
    139     except:
    140         ('did not connect')
    141     s.close()
    142 
    143 
    144 def getfilms(filmfolder):
    145     #get a list of films, in order of settings.p file last modified
    146     films_sorted = []
    147     #print(filmfolder)
    148     films = next(os.walk(filmfolder))[1]
    149     for i in films:
    150         if os.path.isfile(filmfolder + i + '/settings.p') == True:
    151             lastupdate = os.path.getmtime(filmfolder + i + '/' + 'settings.p')
    152             films_sorted.append((i,lastupdate))
    153     films_sorted = sorted(films_sorted, key=lambda tup: tup[1], reverse=True)
    154     #print(films_sorted)
    155     return films_sorted
    156 
    157 #------------Count scenes--------
    158 
    159 def countscenes(filmfolder, filmname):
    160     scenes = 0
    161     try:
    162         allfiles = os.listdir(filmfolder + filmname)
    163     except:
    164         allfiles = []
    165         scenes = 0
    166     for a in allfiles:
    167         if 'scene' in a:
    168             scenes = scenes + 1
    169     return scenes
    170 
    171 #------------Count shots--------
    172 
    173 def countshots(filmname, filmfolder, scene):
    174     shots = 0
    175     try:
    176         allfiles = os.listdir(filmfolder + filmname + '/scene' + str(scene).zfill(3))
    177     except:
    178         allfiles = []
    179         shots = 0
    180     for a in allfiles:
    181         if 'shot' in a:
    182             shots = shots + 1
    183     return shots
    184 
    185 #------------Count takes--------
    186 
    187 def counttakes(filmname, filmfolder, scene, shot):
    188     takes = 0
    189     try:
    190         allfiles = os.listdir(filmfolder + filmname + '/scene' + str(scene).zfill(3) + '/shot' + str(shot).zfill(3))
    191     except:
    192         allfiles = []
    193         return takes
    194     for a in allfiles:
    195         if '.mp4' in a or '.h264' in a:
    196             takes = takes + 1
    197     return takes
    198 
    199 def checkpicture(thumbdir,scene,shot,take):
    200     if os.path.isfile(thumbdir) == False:
    201         return "/"+filmfolder+name+"/scene"+str(scene).zfill(3)+"/shot"+str(shot).zfill(3)+"/picture"+str(take).zfill(3)+".jpeg"
    202     else:
    203         return ''
    204 
    205 def if_exist(dir):
    206     print(basedir+dir)
    207     if os.path.isfile(basedir+dir) == False:
    208         print('thumb not exist')
    209         return False
    210     else:
    211         print('thumb is')
    212         return True
    213 
    214 def countsize(filename):
    215     size = 0
    216     if type(filename) is str:
    217         size = os.stat(filename).st_size
    218     else:
    219         return 0
    220     return size/1024
    221 
    222 def checkvideo(video,filmfolder,film,scene,shot,take):
    223     if take==None:
    224         take=1
    225     #print(basedir+video)
    226     p = "/"+filmfolder+film+"/scene"+str(scene).zfill(3)+"/shot"+str(shot).zfill(3)+ "/picture"+str(take).zfill(3)+".jpeg"
    227     #print(p)
    228     v = ''
    229     if video != '':
    230         try:
    231             if os.stat(basedir+video).st_size == 0:
    232                 v = ''
    233             else:
    234                 v='video'
    235         except:
    236             v = ''
    237     if os.path.isfile(basedir+p) == True:
    238         return p, v
    239     return '', v
    240 
    241 def has_audio_track(file_path):
    242     try:
    243         # Parse the media file
    244         media_info = MediaInfo.parse(file_path)
    245         
    246         # Check for audio tracks
    247         for track in media_info.tracks:
    248             if track.track_type == "Audio":
    249                 return True
    250         return False
    251 
    252     except Exception as e:
    253         print(f"Error parsing {file_path}: {e}")
    254         return None
    255 
    256 class intro:
    257     def GET(self):
    258         return render.intro()
    259 
    260 class index:
    261     def GET(self):
    262         global recording
    263         films = getfilms(filmfolder)
    264         renderedfilms = []
    265         unrenderedfilms = []
    266         allfilms = []
    267         for f in films:
    268             if os.path.isfile(filmfolder + f[0] + '/' + f[0] + '.mp4') == True:
    269                 renderedfilms.append(f[0])
    270                 allfilms.append(f[0])
    271             else:
    272                 unrenderedfilms.append(f[0])
    273                 allfilms.append(f[0])
    274         i=web.input(func=None,selected=None)
    275         if i.selected != None:
    276             sendtocamera(ip,port,'SELECTED:'+i.selected)
    277         if i.func == 'search':
    278             session.cameras=[]
    279             # ping ip every 10 sec while not recording to connect cameras
    280             pingip=0
    281             while pingip < 255 :
    282                 pingip+=1
    283                 pingtocamera(network[:-3]+str(pingip),port,'PING')
    284         elif i.func == 'record':
    285             sendtocamera(ip,port,'RECORD')
    286         elif i.func == 'retake':
    287             print('retake')
    288         elif i.func == 'up':
    289             sendtocamera(ip,port,'UP')
    290         elif i.func == 'down':
    291             sendtocamera(ip,port,'DOWN')
    292         elif i.func == 'left':
    293             sendtocamera(ip,port,'LEFT')
    294         elif i.func == 'right':
    295             sendtocamera(ip,port,'RIGHT')
    296         elif i.func == 'view':
    297             sendtocamera(ip,port,'VIEW')
    298         elif i.func == 'middle':
    299             sendtocamera(ip,port,'MIDDLE')
    300         elif i.func == 'delete':
    301             sendtocamera(ip,port,'DELETE')
    302         elif i.func == 'picture':
    303             sendtocamera(ip,port,'PICTURE')
    304             session.randhash = hashlib.md5(str(random.getrandbits(256)).encode('utf-8')).hexdigest()
    305             session.reload = 1
    306         elif i.func == 'camera0':
    307             sendtocamera(ip,port,'CAMERA:0')
    308         elif i.func == 'camera1':
    309             sendtocamera(ip,port,'CAMERA:1')
    310         elif i.func == 'camera2':
    311             sendtocamera(ip,port,'CAMERA:2')
    312         elif i.func == 'camera3':
    313             sendtocamera(ip,port,'CAMERA:3')
    314         elif i.func == 'camera4':
    315             sendtocamera(ip,port,'CAMERA:4')
    316         elif i.func == 'camera5':
    317             sendtocamera(ip,port,'CAMERA:5')
    318         elif i.func == 'camera6':
    319             sendtocamera(ip,port,'CAMERA:6')
    320         elif i.func == 'camera7':
    321             sendtocamera(ip,port,'CAMERA:7')
    322         elif i.func == 'camera8':
    323             sendtocamera(ip,port,'CAMERA:8')
    324         elif i.func == 'move':
    325             sendtocamera(ip,port,'move')
    326         elif i.func == 'copy':
    327             sendtocamera(ip,port,'copy')
    328         elif i.func == 'paste':
    329             sendtocamera(ip,port,'paste')
    330         interface=open('/dev/shm/interface','r')
    331         vumeter=open('/dev/shm/vumeter','r')
    332         menu=interface.readlines()
    333         vumetermessage=vumeter.readlines()[0].rstrip('\n')
    334         try:
    335             selected=int(menu[0])
    336         except:
    337             selected=0
    338         try:
    339             name=menu[3].split(':')[1]
    340             name=name.rstrip('\n')
    341         except:
    342             name=''
    343         try:
    344             scene=menu[4].split(':')[1].split('/')[0]
    345         except:
    346             scene=1
    347         try:
    348             shot=menu[5].split(':')[1].split('/')[0]
    349         except:
    350             shot=1
    351         try:
    352             take=menu[6].split(':')[1].split('/')[0]
    353         except:
    354             take=1
    355             session.reload = 0
    356         if i.func == 'retake': 
    357             print(i.func)
    358             if recording == False:
    359                 #sendtocamera(ip,port,'RETAKE:'+shot)
    360                 sendtocamera(ip,port,'RETAKE')
    361                 recording = True
    362             else:
    363                 sendtocamera(ip,port,'STOPRETAKE')
    364                 recording = False
    365         if i.func != None:
    366             time.sleep(1)
    367             session.reload = 1
    368             raise web.seeother('/c/')
    369         thumb="/"+filmfolder+name+"/scene"+str(scene).zfill(3)+"/shot"+str(shot).zfill(3)+"/picture"+str(take).zfill(3)+".jpeg"
    370         #print(thumb)
    371         if os.path.isfile(basedir+thumb) == False:
    372             print(basedir+thumb)
    373             thumb=''
    374         return render.index(allfilms, session.cameras, menu, selected,name,scene,shot,take,str,session.randhash,thumb,vumetermessage,i.func,filmfolder)
    375 
    376 class films:
    377     def GET(self, film):
    378         shots = 0
    379         takes = 0
    380         gonzopifilms = getfilms(filmfolder)
    381         renderedfilms = []
    382         unrenderedfilms = []
    383         allfilms = []
    384         for f in gonzopifilms:
    385             if os.path.isfile(filmfolder + f[0] + '/' + f[0] + '.mp4') == True:
    386                 renderedfilms.append(f[0])
    387                 allfilms.append(f[0])
    388             else:
    389                 unrenderedfilms.append(f[0])
    390                 allfilms.append(f[0])
    391         i = web.input(page=None, scene=None, shot=None, take=None, film=None, randhash=None)
    392         if i.scene != None:
    393             shots = countshots(film, filmfolder, i.scene)
    394             takes = counttakes(film, filmfolder, i.scene, i.shot)
    395         if i.scene != None and i.shot != None:
    396             shots = countshots(film, filmfolder, i.scene)
    397         if i.randhash == None:
    398             randhash = hashlib.md5(str(random.getrandbits(256)).encode('utf-8')).hexdigest()
    399         scenes = countscenes(filmfolder, film)
    400         return render.filmpage(allfilms, film, scenes, str, filmfolder, counttakes, countshots, shots, i.scene, takes, i.shot, i.take, checkvideo, randhash)
    401 
    402 class tree:
    403     def GET(self, film):
    404         shots = 0
    405         takes = 0
    406         gonzopifilms = getfilms(filmfolder)
    407         renderedfilms = []
    408         unrenderedfilms = []
    409         allfilms = []
    410         for f in gonzopifilms:
    411             if os.path.isfile(filmfolder + f[0] + '/' + f[0] + '.mp4') == True:
    412                 renderedfilms.append(f[0])
    413                 allfilms.append(f[0])
    414             else:
    415                 unrenderedfilms.append(f[0])
    416                 allfilms.append(f[0])
    417         i = web.input(page=None, scene=None, shot=None, take=None, film=None, randhash=None)
    418         if i.scene != None:
    419             shots = countshots(film, filmfolder, i.scene)
    420             takes = counttakes(film, filmfolder, i.scene, i.shot)
    421         if i.scene != None and i.shot != None:
    422             shots = countshots(film, filmfolder, i.scene)
    423         if i.randhash == None:
    424             randhash = hashlib.md5(str(random.getrandbits(256)).encode('utf-8')).hexdigest()
    425         scenes = countscenes(filmfolder, film)
    426         return render2.tree(allfilms, film, scenes, str, filmfolder, counttakes, countshots, countscenes, shots, i.scene, takes, i.shot, i.take, checkvideo, randhash, if_exist)
    427 
    428 class player:
    429     def GET(self, film):
    430         i=web.input(scene=None,shot=None,take=None)
    431         randhash = hashlib.md5(str(random.getrandbits(256)).encode('utf-8')).hexdigest()
    432         return render.player(real_filmfolder,filmfolder,film,i.scene,i.shot,i.take,str,randhash,has_audio_track)
    433 
    434 class api:
    435     def GET(self):
    436         global menuold, vumeterold
    437         i=web.input(func=None,selected=None)
    438         if i.func == 'record':
    439             sendtocamera(ip,port,'RECORD')
    440         elif i.func == 'retake':
    441             sendtocamera(ip,port,'RETAKE')
    442         elif i.func == 'up':
    443             sendtocamera(ip,port,'UP')
    444         elif i.func == 'down':
    445             sendtocamera(ip,port,'DOWN')
    446         elif i.func == 'left':
    447             sendtocamera(ip,port,'LEFT')
    448         elif i.func == 'right':
    449             sendtocamera(ip,port,'RIGHT')
    450         elif i.func == 'view':
    451             sendtocamera(ip,port,'VIEW')
    452         elif i.func == 'middle':
    453             sendtocamera(ip,port,'MIDDLE')
    454         elif i.func == 'delete':
    455             sendtocamera(ip,port,'DELETE')
    456         elif i.func == 'picture':
    457             sendtocamera(ip,port,'PICTURE')
    458         elif i.func == 'camera0':
    459             sendtocamera(ip,port,'CAMERA:0')
    460         elif i.func == 'camera1':
    461             sendtocamera(ip,port,'CAMERA:1')
    462         elif i.func == 'camera2':
    463             sendtocamera(ip,port,'CAMERA:2')
    464         elif i.func == 'camera3':
    465             sendtocamera(ip,port,'CAMERA:3')
    466         elif i.func == 'camera4':
    467             sendtocamera(ip,port,'CAMERA:4')
    468         elif i.func == 'camera5':
    469             sendtocamera(ip,port,'CAMERA:5')
    470         elif i.func == 'camera6':
    471             sendtocamera(ip,port,'CAMERA:6')
    472         elif i.func == 'camera7':
    473             sendtocamera(ip,port,'CAMERA:7')
    474         elif i.func == 'camera8':
    475             sendtocamera(ip,port,'CAMERA:8')
    476         elif i.func == 'move':
    477             sendtocamera(ip,port,'move')
    478         elif i.func == 'copy':
    479             sendtocamera(ip,port,'copy')
    480         elif i.func == 'paste':
    481             sendtocamera(ip,port,'paste')
    482         interface=open('/dev/shm/interface','r')
    483         menu=interface.readlines()
    484         vumeter=open('/dev/shm/vumeter','r')
    485         vumetermessage=vumeter.readlines()[0].rstrip('\n')
    486         if menu != menuold or vumetermessage != vumeterold:
    487             menuold=menu
    488             vumeterold=vumetermessage
    489             #print(menu)
    490             menudone=''
    491             p=0
    492             film=None
    493             selectfilm=False
    494             if menu != '':
    495                 scene=1
    496                 shot=1
    497                 take=1
    498                 for i in menu:
    499                     if p == 0:
    500                         selected=int(i)+3
    501                     if p > 1:
    502                         if selected == p:
    503                             #menudone=menudone+'<b> '+i.rstrip('\n')+' </b> | '
    504                             menudone=menudone+'<ka style="text-decoration:none; font-size:20px;" color:fff;" href="">'+i+'</ka>'
    505                         else:
    506                             #menudone=menudone+i.rstrip('\n')+' | '
    507                             menudone=menudone+'<a style="text-decoration:none; font-size:20px;" href="?selected='+str(p-3)+'"> '+i+' </a>'
    508                         #if p == 7:
    509                         #    menudone=menudone+'<br>'
    510                         #if p == 13:
    511                         #    menudone=menudone+'<br>'
    512                         #if p == 21:
    513                         #    menudone=menudone+'<br>'
    514                         #if p == 30:
    515                         #    menudone=menudone+'<br>'
    516                     if p == 2 and i.rstrip('\n') == 'Up and down to select and load film':
    517                         selectfilm=True
    518                     if p == 3 and selectfilm==True:
    519                         try:
    520                             film=i.split(':')[1].rstrip('\n')
    521                         except:
    522                             film=None
    523                     if p == 4 and selectfilm == False:
    524                         try:
    525                             film=i.split(':')[1].rstrip('\n')
    526                         except:
    527                             film=None
    528                     if p == 5 and film != None:
    529                         try:
    530                             scene=int(i.split(':')[1].split('/')[0])
    531                         except:
    532                             scene=1
    533                     if p == 6 and film != None:
    534                         try:
    535                             shot=int(i.split(':')[1].split('/')[0])
    536                         except:
    537                             shot=1
    538                     if p == 7 and film != None:
    539                         try:
    540                             take=int(i.split(':')[1].split('/')[0])
    541                         except:
    542                             take=1
    543                     if p > 0 and selected == 423:
    544                         menudone=menudone+'<ka style="text-decoration:none; font-size:20px;" color:fff;" href="">'+i+'</ka>'
    545                     #if p > 2 and film == None:
    546                         #menudone=menudone+'<ka style="text-decoration:none; font-size:20px;" color:fff;" href="">'+i+'</ka>'
    547                     p = p + 1
    548             thumb = ''
    549             video = ''
    550             if film != None:
    551                 if selected == 0:
    552                     video = '/p/'+film
    553                     menudone+=menudone+'video'
    554                 if selected == 4:
    555                     video = '/p/'+film
    556                 elif selected == 5:
    557                     video = '/p/'+film+'?scene=' + str(scene)
    558                 elif selected == 6:
    559                     video = '/p/'+film+'?scene='+str(scene)+'&shot='+str(shot)+'&take='+str(take)
    560                 elif selected == 7:
    561                     video = '/p/'+film+'?scene='+str(scene)+'&shot='+str(shot)+'&take='+str(take)
    562                 else:
    563                     video = '/p/'+film+'?scene='+str(scene)+'&shot='+str(shot)+'&take='+str(take)
    564                 thumb = '/'+filmfolder + film + "/scene" + str(scene).zfill(3) + "/shot" + str(shot).zfill(3) + "/take" + str(take).zfill(3) + ".jpeg" 
    565             if os.path.isfile(basedir+thumb) == True:
    566                 randhashimg = '?'+hashlib.md5(str(random.getrandbits(256)).encode('utf-8')).hexdigest()
    567                 writemenu=menudone+'<br><br>'+vumetermessage+'<br><a href="'+video+'"><img src="'+thumb+randhashimg+'"></a>'
    568                 #writemenu=menudone+render.player(filmfolder,film,scene,shot,take,str)
    569             else:
    570                 writemenu=menudone+'<br><br>'+vumetermessage+'<br>'
    571             f = open(basedir+'/static/menu.html', 'w')
    572             f.write(writemenu)
    573             f.close()
    574 
    575 application = app.wsgifunc()
    576