Subir archivos a "/"

This commit is contained in:
2025-06-16 20:41:11 +00:00
parent d18c7723aa
commit 40e039ae2e
2 changed files with 326 additions and 0 deletions

243
synothumb.py Normal file
View File

@ -0,0 +1,243 @@
#!/usr/bin/env python
# cd; mkdir mnt_photo
# sudo mount -t {synology-ip-address}:/volume1/photo mnt_photo/
# Author: phillips321
# Co-authors: devdogde, sirrahd, AndrewFreemantle
# License: CC BY-SA 3.0
# Use: home use only, commercial use by permission only
# Released: www.phillips321.co.uk
# Instructions: www.fatlemon.co.uk/synothumbs
# Dependencies: Pillow, libjpeg, libpng, dcraw, ffmpeg
# Supports: jpg, png, tif, bmp, cr2 (raw), mov, m4v, mp4
import os,sys,threading,time,subprocess,shlex
from Queue import Queue
from PIL import Image,ImageChops #PIL is provided by Pillow
from io import StringIO
#########################################################################
# Settings
#########################################################################
NumOfThreads=8 # Number of threads
startTime=time.time()
imageExtensions=['.jpg','.png','.jpeg','.tif','.bmp','.cr2'] #possibly add other raw types?
videoExtensions=['.mov','.m4v','mp4']
xlName="SYNOPHOTO_THUMB_XL.jpg" ; xlSize=(1280,1280) #XtraLarge
lName="SYNOPHOTO_THUMB_L.jpg" ; lSize=(800,800) #Large
bName="SYNOPHOTO_THUMB_B.jpg" ; bSize=(640,640) #Big
mName="SYNOPHOTO_THUMB_M.jpg" ; mSize=(320,320) #Medium
sName="SYNOPHOTO_THUMB_S.jpg" ; sSize=(160,160) #Small
pName="SYNOPHOTO_THUMB_PREVIEW.jpg" ; pSize=(120,160) #Preview, keep ratio, pad with black
#########################################################################
# Images Class
#########################################################################
class convertImage(threading.Thread):
def __init__(self,queueIMG,badImageFileList):
threading.Thread.__init__(self)
self.queueIMG=queueIMG
self.badImageFileList=badImageFileList
def run(self):
while True:
self.imagePath=self.queueIMG.get()
self.imageDir,self.imageName = os.path.split(self.imagePath)
self.thumbDir=os.path.join(self.imageDir,"@eaDir",self.imageName)
print (" [-] Now working on %s" % (self.imagePath))
if os.path.isfile(os.path.join(self.thumbDir,xlName)) != 1:
if os.path.isdir(self.thumbDir) != 1:
try:os.makedirs(self.thumbDir)
except:continue
#Following if statements converts raw images using dcraw first
if os.path.splitext(self.imagePath)[1].lower() == ".cr2":
self.dcrawcmd = "dcraw -c -b 8 -q 0 -w -H 5 '%s'" % self.imagePath
self.dcraw_proc = subprocess.Popen(shlex.split(self.dcrawcmd), stdout=subprocess.PIPE)
self.raw = StringIO(self.dcraw_proc.communicate()[0])
self.image=Image.open(self.raw)
else:
self.image=Image.open(self.imagePath)
###### Check image orientation and rotate if necessary
## code adapted from: http://www.lifl.fr/~riquetd/auto-rotating-pictures-using-pil.html
try:
self.exif = self.image._getexif()
except:
pass
if self.exif:
self.orientation_key = 274 # cf ExifTags
if self.orientation_key in self.exif:
self.orientation = self.exif[self.orientation_key]
rotate_values = {
3: 180,
6: 270,
8: 90
}
try:
if self.orientation in rotate_values:
self.image=self.image.rotate(rotate_values[self.orientation])
except:
pass
#### end of orientation part
try:
self.image.thumbnail(xlSize, Image.ANTIALIAS)
self.image.save(os.path.join(self.thumbDir,xlName), quality=90)
self.image.thumbnail(lSize, Image.ANTIALIAS)
self.image.save(os.path.join(self.thumbDir,lName), quality=90)
self.image.thumbnail(bSize, Image.ANTIALIAS)
self.image.save(os.path.join(self.thumbDir,bName), quality=90)
self.image.thumbnail(mSize, Image.ANTIALIAS)
self.image.save(os.path.join(self.thumbDir,mName), quality=90)
self.image.thumbnail(sSize, Image.ANTIALIAS)
self.image.save(os.path.join(self.thumbDir,sName), quality=90)
self.image.thumbnail(pSize, Image.ANTIALIAS)
# pad out image
self.image_size = self.image.size
self.preview_img = self.image.crop((0, 0, pSize[0], pSize[1]))
self.offset_x = max((pSize[0] - self.image_size[0]) / 2, 0)
self.offset_y = max((pSize[1] - self.image_size[1]) / 2, 0)
self.preview_img = ImageChops.offset(self.preview_img, int(self.offset_x), int(self.offset_y)) # offset has to be integer, not float
self.preview_img.save(os.path.join(self.thumbDir,pName), quality=90)
except IOError:
## image file is corrupt / can't be read / or we can't write to the mounted share
with open(self.badImageFileList, "a") as badFileList:
badFileList.write(self.imagePath + '\n')
self.queueIMG.task_done()
#########################################################################
# Video Class
#########################################################################
class convertVideo(threading.Thread):
def __init__(self,queueVID):
threading.Thread.__init__(self)
self.queueVID=queueVID
def is_tool(self, name):
try:
devnull = open(os.devnull)
subprocess.Popen([name], stdout=devnull, stderr=devnull).communicate()
except OSError as e:
if e.errno == os.errno.ENOENT:
return False
return True
def run(self):
while True:
self.videoPath=self.queueVID.get()
self.videoDir,self.videoName = os.path.split(self.videoPath)
self.thumbDir=os.path.join(self.videoDir,"@eaDir",self.videoName)
if os.path.isfile(os.path.join(self.thumbDir,xlName)) != 1:
print (" [-] Now working on %s" % (self.videoPath))
if os.path.isdir(self.thumbDir) != 1:
try:os.makedirs(self.thumbDir)
except:
self.queueVID.task_done()
continue
# Check video conversion command and convert video to flv
if self.is_tool("ffmpeg"):
self.ffmpegcmd = "ffmpeg -loglevel panic -i '%s' -y -ar 44100 -r 12 -ac 2 -f flv -qscale 5 -s 320x180 -aspect 320:180 '%s/SYNOPHOTO:FILM.flv'" % (self.videoPath,self.thumbDir) # ffmpeg replaced by avconv on ubuntu
elif self.is_tool("avconv"):
self.ffmpegcmd = "avconv -loglevel panic -i '%s' -y -ar 44100 -r 12 -ac 2 -f flv -qscale 5 -s 320x180 -aspect 320:180 '%s/SYNOPHOTO:FILM.flv'" % (self.videoPath,self.thumbDir)
else: return False
self.ffmpegproc = subprocess.Popen(shlex.split(self.ffmpegcmd), stdout=subprocess.PIPE)
self.ffmpegproc.communicate()[0]
# Create video thumbs
self.tempThumb=os.path.join("/tmp",os.path.splitext(self.videoName)[0]+".jpg")
if self.is_tool("ffmpeg"):
self.ffmpegcmdThumb = "ffmpeg -loglevel panic -i '%s' -y -an -ss 00:00:01 -an -r 1 -vframes 1 '%s'" % (self.videoPath,self.tempThumb) # ffmpeg replaced by avconv on ubuntu
elif self.is_tool("avconv"):
self.ffmpegcmdThumb = "avconv -loglevel panic -i '%s' -y -an -ss 00:00:01 -an -r 1 -vframes 1 '%s'" % (self.videoPath,self.tempThumb)
else: return False
try:
self.ffmpegThumbproc = subprocess.Popen(shlex.split(self.ffmpegcmdThumb), stdout=subprocess.PIPE)
self.ffmpegThumbproc.communicate()[0]
self.image=Image.open(self.tempThumb)
self.image.thumbnail(xlSize)
self.image.save(os.path.join(self.thumbDir,xlName))
self.image.thumbnail(mSize)
self.image.save(os.path.join(self.thumbDir,mName))
except:
self.queueVID.task_done()
continue
self.queueVID.task_done()
#########################################################################
# Main
#########################################################################
def main():
queueIMG = Queue()
queueVID = Queue()
try:
rootdir=sys.argv[1]
except:
print ("Usage: %s directory" % sys.argv[0])
sys.exit(0)
# Finds all images of type in extensions array
imageList=[]
print ("[+] Looking for images and populating queue (This might take a while...)")
for path, subFolders, files in os.walk(rootdir):
for file in files:
ext=os.path.splitext(file)[1].lower()
if any(x in ext for x in imageExtensions):#check if extensions matches ext
if "@eaDir" not in path:
if file != "Thumbs.db" and file[0] != ".": # maybe remove
imageList.append(os.path.join(path,file))
print ("[+] We have found %i images in search directory" % len(imageList))
#input("\tPress Enter to continue or Ctrl-C to quit")
#spawn a pool of threads
for i in range(NumOfThreads): #number of threads
t=convertImage(queueIMG, os.path.join(rootdir, "synothumb-bad-file-list.txt"))
t.setDaemon(True)
t.start()
# populate queue with Images
for imagePath in imageList:
queueIMG.put(imagePath)
queueIMG.join()
# Finds all videos of type in extensions array
videoList=[]
print ("[+] Looking for videos and populating queue (This might take a while...)")
for path, subFolders, files in os.walk(rootdir):
for file in files:
ext=os.path.splitext(file)[1].lower()
if any(x in ext for x in videoExtensions):#check if extensions matches ext
if "@eaDir" not in path:
if file != "Thumbs.db" and file[0] != ".": #maybe remove?
videoList.append(os.path.join(path,file))
print ("[+] We have found %i videos in search directory" % len(videoList))
#input("\tPress Enter to continue or Ctrl-C to quit")
#spawn a pool of threads
for i in range(NumOfThreads): #number of threads
v=convertVideo(queueVID)
v.setDaemon(True)
v.start()
# populate queueVID with Images
for videoPath in videoList:
queueVID.put(videoPath) # could we possibly put this instead of videoList.append(os.path.join(path,file))
queueVID.join()
endTime=time.time()
print ("Time to complete %i" % (endTime-startTime))
sys.exit(0)
if __name__ == "__main__":
main()