Subir archivos a "/"
This commit is contained in:
83
set-fortivpn-dns.sh
Normal file
83
set-fortivpn-dns.sh
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# === Configuración ===
|
||||||
|
VPN_NAME="FortiClient VPN"
|
||||||
|
DNS1="10.7.120.30"
|
||||||
|
DNS2="10.7.120.31"
|
||||||
|
RESOLVER_FILE="/etc/resolver/ttech.inet"
|
||||||
|
DNS_BACKUP_FILE="$HOME/.fortivpn_dns_backup"
|
||||||
|
NOTIFIER="/opt/homebrew/bin/terminal-notifier" # Ajusta según tu sistema
|
||||||
|
|
||||||
|
# === Protección anti-ejecución múltiple ===
|
||||||
|
LOCK_FILE="/tmp/set-fortivpn-dns.lock"
|
||||||
|
LOCK_TIMEOUT=10 # segundos
|
||||||
|
|
||||||
|
if [ -f "$LOCK_FILE" ]; then
|
||||||
|
last_run=$(stat -f "%m" "$LOCK_FILE")
|
||||||
|
now=$(date +%s)
|
||||||
|
if (( now - last_run < LOCK_TIMEOUT )); then
|
||||||
|
echo "$(date): Script ejecutado recientemente. Saliendo." >> /tmp/fortivpn-dns.log
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
touch "$LOCK_FILE"
|
||||||
|
|
||||||
|
# === Función para notificaciones ===
|
||||||
|
function notify() {
|
||||||
|
TITLE="$1"
|
||||||
|
MESSAGE="$2"
|
||||||
|
USER=$(stat -f "%Su" /dev/console)
|
||||||
|
sudo -u "$USER" "$NOTIFIER" -title "$TITLE" -message "$MESSAGE"
|
||||||
|
}
|
||||||
|
|
||||||
|
# === Detectar estado de la VPN ===
|
||||||
|
STATUS=$(scutil --nc status "$VPN_NAME" | head -n 1)
|
||||||
|
echo $STATUS
|
||||||
|
|
||||||
|
if [[ "$STATUS" == "Connected" ]]; then
|
||||||
|
if [[ -f "$RESOLVER_FILE" ]]; then
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "$(date): VPN conectada." >> /tmp/fortivpn-dns.log
|
||||||
|
|
||||||
|
# Guardar DNS originales si no están guardados
|
||||||
|
if [[ ! -f "$DNS_BACKUP_FILE" ]]; then
|
||||||
|
networksetup -getdnsservers "$VPN_NAME" > "$DNS_BACKUP_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Aplicar nuevos DNS
|
||||||
|
networksetup -setdnsservers "$VPN_NAME" $DNS1 $DNS2
|
||||||
|
|
||||||
|
# Crear resolver para ttech.inet
|
||||||
|
if [[ ! -f "$RESOLVER_FILE" ]]; then
|
||||||
|
sudo /bin/mkdir -p /etc/resolver
|
||||||
|
echo "nameserver $DNS1" | sudo /usr/bin/tee "$RESOLVER_FILE" > /dev/null
|
||||||
|
echo "nameserver $DNS2" | sudo /usr/bin/tee -a "$RESOLVER_FILE" > /dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
notify "✅ VPN Conectada" "DNS configurado y resolver ttech.inet creado"
|
||||||
|
|
||||||
|
else
|
||||||
|
echo "$(date): VPN desconectada." >> /tmp/fortivpn-dns.log
|
||||||
|
|
||||||
|
# Restaurar DNS originales
|
||||||
|
if [[ -f "$DNS_BACKUP_FILE" ]]; then
|
||||||
|
ORIGINAL_DNS=$(cat "$DNS_BACKUP_FILE")
|
||||||
|
if [[ "$ORIGINAL_DNS" == "There aren't any DNS Servers set on"* ]]; then
|
||||||
|
networksetup -setdnsservers "$VPN_NAME" "Empty"
|
||||||
|
else
|
||||||
|
networksetup -setdnsservers "$VPN_NAME" $ORIGINAL_DNS
|
||||||
|
fi
|
||||||
|
rm "$DNS_BACKUP_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Eliminar resolver
|
||||||
|
if [[ -f "$RESOLVER_FILE" ]]; then
|
||||||
|
sudo /bin/rm -f "$RESOLVER_FILE"
|
||||||
|
notify "🔌 VPN Desconectada" "DNS restaurado y resolver eliminado"
|
||||||
|
fi
|
||||||
|
|
||||||
|
#notify "🔌 VPN Desconectada" "DNS restaurado y resolver eliminado"
|
||||||
|
fi
|
||||||
243
synothumb.py
Normal file
243
synothumb.py
Normal 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()
|
||||||
Reference in New Issue
Block a user