Moved old files to modules from root folder.
This commit is contained in:
@@ -1,19 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# @Author: KevinMidboe
|
|
||||||
# @Date: 2017-03-04 14:56:30
|
|
||||||
# @Last Modified by: KevinMidboe
|
|
||||||
# @Last Modified time: 2017-03-04 15:27:02
|
|
||||||
|
|
||||||
from pasteee import Paste
|
|
||||||
|
|
||||||
def main():
|
|
||||||
pasteText = """Some text to paste
|
|
||||||
Some more text
|
|
||||||
Foo bar baz
|
|
||||||
"""
|
|
||||||
paste = Paste(pasteText, private=False, desc="My first paste", views=15)
|
|
||||||
print(paste)
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
||||||
@@ -1,211 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# @Author: KevinMidboe
|
|
||||||
# @Date: 2017-04-05 18:40:11
|
|
||||||
# @Last Modified by: KevinMidboe
|
|
||||||
# @Last Modified time: 2017-04-06 15:58:48
|
|
||||||
import os.path, hashlib, time, glob, sqlite3, re, json, tweepy
|
|
||||||
from functools import reduce
|
|
||||||
from fuzzywuzzy import process
|
|
||||||
from langdetect import detect
|
|
||||||
from time import sleep
|
|
||||||
import env
|
|
||||||
|
|
||||||
dirHash = None
|
|
||||||
childList = []
|
|
||||||
|
|
||||||
class twitter(object):
|
|
||||||
def __init__(self):
|
|
||||||
if '' in [env.consumer_key, env.consumer_secret, env.access_token, env.access_token_secret]:
|
|
||||||
print('not set')
|
|
||||||
|
|
||||||
self.consumer_key = env.consumer_key
|
|
||||||
self.consumer_secret = env.consumer_secret
|
|
||||||
self.access_token = env.access_token
|
|
||||||
self.access_token_secret = env.access_token_secret
|
|
||||||
|
|
||||||
self.authenticate()
|
|
||||||
|
|
||||||
def authenticate(self):
|
|
||||||
auth = tweepy.OAuthHandler(self.consumer_key, self.consumer_secret)
|
|
||||||
auth.set_access_token(self.access_token, self.access_token_secret)
|
|
||||||
self.api_token = tweepy.API(auth)
|
|
||||||
|
|
||||||
def api(self):
|
|
||||||
return self.api_token
|
|
||||||
|
|
||||||
class mediaItem(object):
|
|
||||||
def __init__(self, parent, childrenList):
|
|
||||||
self.parent = parent
|
|
||||||
self.children = childrenList
|
|
||||||
self._id = hashlib.md5("b'{}'".format(self.parent).encode()).hexdigest()[:6]
|
|
||||||
self.showName = self.findSeriesName()
|
|
||||||
self.season = self.getSeasonNumber()
|
|
||||||
self.episode = self.getEpisodeNumber()
|
|
||||||
self.videoFiles = []
|
|
||||||
self.subtitles = []
|
|
||||||
self.trash = []
|
|
||||||
self.getMediaItems()
|
|
||||||
|
|
||||||
self.saveToDB()
|
|
||||||
self.notifyInsert()
|
|
||||||
|
|
||||||
|
|
||||||
def findSeriesName(self):
|
|
||||||
find = re.compile("^[a-zA-Z. ]*")
|
|
||||||
m = re.match(find, self.parent)
|
|
||||||
if m:
|
|
||||||
name, hit = process.extractOne(m.group(0), getShowNames().keys())
|
|
||||||
if hit >= 90:
|
|
||||||
return name
|
|
||||||
else:
|
|
||||||
# This should be logged or handled somehow
|
|
||||||
pass
|
|
||||||
|
|
||||||
def getSeasonNumber(self):
|
|
||||||
m = re.search('[sS][0-9]{1,2}', self.parent)
|
|
||||||
if m:
|
|
||||||
return re.sub('[sS]', '', m.group(0))
|
|
||||||
|
|
||||||
def getEpisodeNumber(self):
|
|
||||||
m = re.search('[eE][0-9]{1,2}', self.parent)
|
|
||||||
if m:
|
|
||||||
return re.sub('[eE]', '', m.group(0))
|
|
||||||
|
|
||||||
def uploaderSignature(self, file):
|
|
||||||
match = re.search('-[a-zA-Z\[\]\-]*.[a-z]{3}', file)
|
|
||||||
if match:
|
|
||||||
uploader = match.group(0)[:-4]
|
|
||||||
return re.sub(uploader, '', file)
|
|
||||||
|
|
||||||
return ''
|
|
||||||
|
|
||||||
def getSubtitlesLang(self, subFile):
|
|
||||||
f = open('/'.join([env.show_dir, self.parent, subFile]), 'r', encoding='ISO-8859-15')
|
|
||||||
language = detect(f.read())
|
|
||||||
f.close()
|
|
||||||
if 'sdh' in subFile.lower():
|
|
||||||
return 'sdh.' + language
|
|
||||||
return language
|
|
||||||
|
|
||||||
def getMediaItems(self):
|
|
||||||
for child in self.children:
|
|
||||||
if child[-3:] in env.mediaExt and child[:-4] not in env.mediaExcluders:
|
|
||||||
self.videoFiles.append([child, self.uploaderSignature(child)])
|
|
||||||
elif child[-3:] in env.subExt:
|
|
||||||
self.subtitles.append([child, self.uploaderSignature(child), self.getSubtitlesLang(child)])
|
|
||||||
else:
|
|
||||||
self.trash.append(child)
|
|
||||||
|
|
||||||
def notifyInsert(self):
|
|
||||||
# Send unique id. (time)
|
|
||||||
tweetObj = twitter()
|
|
||||||
api = tweetObj.api()
|
|
||||||
tweetString = 'Added episode:\n' + self.showName + ' S' + self.season\
|
|
||||||
+ 'E' + self.episode + '\nDetails: \n https://kevinmidboe.com/seasoned/verified.html?id=' + self._id
|
|
||||||
response = api.send_direct_message('kevinmidboe', text=tweetString)
|
|
||||||
|
|
||||||
|
|
||||||
def saveToDB(self):
|
|
||||||
# TODO Setup script
|
|
||||||
conn = sqlite3.connect(env.db_path)
|
|
||||||
c = conn.cursor()
|
|
||||||
|
|
||||||
path = '/'.join([env.show_dir, self.parent])
|
|
||||||
video_files = json.dumps(self.videoFiles)
|
|
||||||
subtitles = json.dumps(self.subtitles)
|
|
||||||
trash = json.dumps(self.trash)
|
|
||||||
|
|
||||||
try:
|
|
||||||
c.execute("INSERT INTO stray_eps ('id', 'parent', 'path', 'name', 'season', 'episode', 'video_files', 'subtitles', 'trash') VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", \
|
|
||||||
[self._id, self.parent, path, self.showName, self.season, self.episode, video_files, subtitles, trash])
|
|
||||||
except sqlite3.IntegrityError:
|
|
||||||
print('Episode already registered')
|
|
||||||
|
|
||||||
conn.commit()
|
|
||||||
conn.close()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def getDirContent(dir=env.show_dir):
|
|
||||||
try:
|
|
||||||
return [d for d in os.listdir(dir) if d[0] != '.']
|
|
||||||
except FileNotFoundError:
|
|
||||||
print('Error: "' + dir + '" is not a directory.')
|
|
||||||
exit(0)
|
|
||||||
|
|
||||||
# Hashes the contents of media folder to easily check for changes.
|
|
||||||
def directoryChecksum():
|
|
||||||
dirList = getDirContent()
|
|
||||||
# Creates a string of all the list items.
|
|
||||||
dirConcat = reduce(lambda x, y: x + y, dirList, "")
|
|
||||||
|
|
||||||
m = hashlib.md5()
|
|
||||||
m.update(bytes(dirConcat, 'utf-16be')) # String to byte conversion.
|
|
||||||
global dirHash
|
|
||||||
if dirHash != m.digest():
|
|
||||||
dirHash = m.digest()
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def getShowNames():
|
|
||||||
conn = sqlite3.connect(env.db_path)
|
|
||||||
c = conn.cursor()
|
|
||||||
|
|
||||||
c.execute('SELECT show_names, date_added, date_modified FROM shows')
|
|
||||||
|
|
||||||
returnList = {}
|
|
||||||
for name, added, modified in c.fetchall():
|
|
||||||
returnList[name] = [added, modified]
|
|
||||||
|
|
||||||
conn.close()
|
|
||||||
return returnList
|
|
||||||
|
|
||||||
def XOR(list1, list2):
|
|
||||||
return set(list1) ^ set(list2)
|
|
||||||
|
|
||||||
def filterChildItems(parent):
|
|
||||||
try:
|
|
||||||
children = getDirContent('/'.join([env.show_dir, parent]))
|
|
||||||
if children:
|
|
||||||
childList.append(mediaItem(parent, children))
|
|
||||||
except FileNotFoundError:
|
|
||||||
# Log to error file
|
|
||||||
print('Error: "' + '/'.join([env.show_dir, parent]) + '" is not a valid directory.')
|
|
||||||
|
|
||||||
def getNewItems():
|
|
||||||
newItems = XOR(getDirContent(), getShowNames())
|
|
||||||
for item in newItems:
|
|
||||||
filterChildItems(item)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
# TODO Verify env variables (showDir)
|
|
||||||
start_time = time.time()
|
|
||||||
if directoryChecksum():
|
|
||||||
conn = sqlite3.connect(env.db_path)
|
|
||||||
c = conn.cursor()
|
|
||||||
|
|
||||||
cursor = c.execute('SELECT * FROM stray_eps WHERE id = "9110df"')
|
|
||||||
episodeList = []
|
|
||||||
for row in c.fetchall():
|
|
||||||
columnNames = [description[0] for description in cursor.description]
|
|
||||||
|
|
||||||
episodeDict = dict.fromkeys(columnNames)
|
|
||||||
|
|
||||||
for i, key in enumerate(episodeDict.keys()):
|
|
||||||
episodeDict[key] = row[i]
|
|
||||||
|
|
||||||
episodeList.append(episodeDict)
|
|
||||||
|
|
||||||
conn.close()
|
|
||||||
print(json.dumps(episodeList))
|
|
||||||
getNewItems()
|
|
||||||
|
|
||||||
print("--- %s seconds ---" % '{0:.4f}'.format((time.time() - start_time)))
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
while True:
|
|
||||||
main()
|
|
||||||
sleep(2)
|
|
||||||
@@ -1,252 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# @Author: KevinMidboe
|
|
||||||
# @Date: 2017-02-23 21:41:40
|
|
||||||
# @Last Modified by: KevinMidboe
|
|
||||||
# @Last Modified time: 2017-03-04 16:32:35
|
|
||||||
|
|
||||||
import os, re, shutil, sqlite3
|
|
||||||
from fuzzywuzzy import process
|
|
||||||
from sys import argv
|
|
||||||
from pprint import pprint
|
|
||||||
|
|
||||||
# TODO Rename file to remove watermark DONE
|
|
||||||
# Look for subs in file and folder DONE
|
|
||||||
# What if there are multiple subs
|
|
||||||
# Add language for subs
|
|
||||||
# Remove stupid samples
|
|
||||||
# Import directory based on OS
|
|
||||||
|
|
||||||
# THE PARTS OF SEASONED FOLDER
|
|
||||||
# DATABASE
|
|
||||||
# Add show
|
|
||||||
# Get list of shows
|
|
||||||
# Add cmdInfoExtractor
|
|
||||||
|
|
||||||
# Parser
|
|
||||||
# Get files from directory
|
|
||||||
# Check files not in shows list
|
|
||||||
# Get best match to the name of file
|
|
||||||
# Get folder contents
|
|
||||||
|
|
||||||
# cmdInfoExtractor
|
|
||||||
# NB: Create folder for new seasons
|
|
||||||
# Folderpath
|
|
||||||
# Show match
|
|
||||||
# Episode/Season
|
|
||||||
# Contents
|
|
||||||
# mediafiles
|
|
||||||
# - removed author
|
|
||||||
# subtitles
|
|
||||||
# - removed author
|
|
||||||
#
|
|
||||||
|
|
||||||
# cmdInfoExecuter
|
|
||||||
# Checks if there is a waiting tweet
|
|
||||||
# Check for replies for the gives tweets
|
|
||||||
# If any has reply (y), execute the cmdInfo
|
|
||||||
# Delete from waiting DB and add to fixed DB
|
|
||||||
|
|
||||||
# Twitter
|
|
||||||
# twitter - [index] = en
|
|
||||||
# - [index] -
|
|
||||||
# - [index] +
|
|
||||||
# trash
|
|
||||||
# twitter - [index] +
|
|
||||||
# - [index] -
|
|
||||||
# - [index] =
|
|
||||||
|
|
||||||
showDir = '/Volumes/media/tv/'
|
|
||||||
dbPath = "/Users/KevinMidboe/Dropbox/python/seasonedShows/shows.db"
|
|
||||||
mediaExtensions = ['mkv', 'mp4', 'avi']
|
|
||||||
subExtensions = ['srt']
|
|
||||||
|
|
||||||
def verifyConnectedDirectory():
|
|
||||||
if not os.path.isdir(showDir):
|
|
||||||
print('Error:', showDir + ' folder not found. Is it mounted?')
|
|
||||||
exit(0)
|
|
||||||
|
|
||||||
def addShowToDB(name):
|
|
||||||
if name in getShowNames():
|
|
||||||
return False
|
|
||||||
|
|
||||||
conn = sqlite3.connect(dbPath)
|
|
||||||
c = conn.cursor()
|
|
||||||
|
|
||||||
c.execute('INSERT INTO shows VALUES ("' + str(name) + '"' + ", datetime('now'), datetime('now'))")
|
|
||||||
|
|
||||||
conn.commit()
|
|
||||||
conn.close()
|
|
||||||
return True
|
|
||||||
|
|
||||||
def addSubLanguage(file):
|
|
||||||
f = open('subs/The.Man.from.U.N.C.L.E.2015.1080p-[eztv].srt', 'r', encoding = "UTF-32")
|
|
||||||
detectedLanguage = detect(f.read())
|
|
||||||
|
|
||||||
# Removes the uploader name from filename
|
|
||||||
def removeUploader(file):
|
|
||||||
match = re.search('-[a-zA-Z\[\]\-]*.[a-z]{3}', file)
|
|
||||||
|
|
||||||
if match and input('Remove uploader:\t' + match.group(0)[:-4] + ' [Y/n] ') != 'n':
|
|
||||||
uploader, ext = match.group(0).split('.')
|
|
||||||
# if ext not in subExtensions:
|
|
||||||
# file = file.replace(uploader, '')
|
|
||||||
# else:
|
|
||||||
# file = file.replace(uploader, '.eng')
|
|
||||||
file = file.replace(uploader, '')
|
|
||||||
return file
|
|
||||||
|
|
||||||
|
|
||||||
def moveEpisode(srcFile, destDir):
|
|
||||||
os.rename(srcFile, destDir)
|
|
||||||
|
|
||||||
def XOR(list1, list2):
|
|
||||||
return set(list1) ^ set(list2)
|
|
||||||
|
|
||||||
def getFuzzyNames(query):
|
|
||||||
return process.extractOne(query, getShowNames().keys())
|
|
||||||
|
|
||||||
# Finds the correct show name
|
|
||||||
def getShowNames():
|
|
||||||
conn = sqlite3.connect(dbPath)
|
|
||||||
c = conn.cursor()
|
|
||||||
|
|
||||||
c.execute('SELECT show_names, date_added, date_modified FROM shows')
|
|
||||||
|
|
||||||
returnList = {}
|
|
||||||
for name, added, modified in c.fetchall():
|
|
||||||
returnList[name] = [added, modified]
|
|
||||||
|
|
||||||
conn.close()
|
|
||||||
return returnList
|
|
||||||
|
|
||||||
# showList = os.listdir(showDir) # Get's list of folders in showDir
|
|
||||||
|
|
||||||
# return process.extractOne(input, showList)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def getSeasons(show):
|
|
||||||
existingShowSeasons = os.listdir(showDir + show)
|
|
||||||
|
|
||||||
seasonsList = []
|
|
||||||
for season in existingShowSeasons:
|
|
||||||
# Checks if folder is given format (Season [0-9]{2}$)
|
|
||||||
if re.search('Season\ [0-9]{2}$', season):
|
|
||||||
# If re finds a match we append the season folder to seasonsList[]
|
|
||||||
seasonsList.append(season[-2:])
|
|
||||||
|
|
||||||
# TODO Return full season name and create list in the if statement at return'
|
|
||||||
return seasonsList
|
|
||||||
|
|
||||||
|
|
||||||
def createEpisodeFolders(show, season, episode, createNew=False):
|
|
||||||
episodeFormat = '%s S%sE'% (show, season)
|
|
||||||
seasonFormat = '%s Season %s/' % (show, season)
|
|
||||||
|
|
||||||
seasonDir = showDir + show + '/' + seasonFormat
|
|
||||||
|
|
||||||
# Creates a season folder if none exists for given season value
|
|
||||||
if createNew == True:
|
|
||||||
os.makedirs(seasonDir)
|
|
||||||
|
|
||||||
episodeList = os.listdir(seasonDir)
|
|
||||||
|
|
||||||
for i in range(1,int(episode)+1):
|
|
||||||
i_formatted = '{:02}'.format(i)
|
|
||||||
if episodeFormat + i_formatted not in episodeList:
|
|
||||||
os.makedirs(seasonDir + episodeFormat + i_formatted)
|
|
||||||
print(' ' + episodeFormat + i_formatted)
|
|
||||||
|
|
||||||
|
|
||||||
# TODO to only get the stray files.
|
|
||||||
# Get all folders without spaces and atleast one '.'
|
|
||||||
def findStray():
|
|
||||||
showNames = getShowNames().keys()
|
|
||||||
folderContents = filter( lambda f: not f.startswith('.'), os.listdir(showDir))
|
|
||||||
|
|
||||||
XORContent = XOR(folderContents, showNames)
|
|
||||||
|
|
||||||
multipleEpisodeRegex = 'complete|season|\.\S[0-9]{1,2}\.'
|
|
||||||
|
|
||||||
# print(set(folderContents) ^ set(showNames))
|
|
||||||
|
|
||||||
for file in XORContent:
|
|
||||||
if re.findall(multipleEpisodeRegex, file.lower()):
|
|
||||||
print(file, process.extractOne(file, showNames))
|
|
||||||
|
|
||||||
|
|
||||||
def findStrayEpisodes(show, season, episode):
|
|
||||||
showList = os.listdir(showDir)
|
|
||||||
|
|
||||||
singleEpisodeRegex = re.sub(' ', '.', show) + '.S' + season + 'E'
|
|
||||||
# Complete season folder : Show + Season | Complete + first(number after show)
|
|
||||||
multipleEpisodeRegex = 'complete|season'
|
|
||||||
|
|
||||||
for file in showList:
|
|
||||||
if re.findall(multipleEpisodeRegex, file.lower()) and show in file:
|
|
||||||
print(file)
|
|
||||||
|
|
||||||
if singleEpisodeRegex in file:
|
|
||||||
episodeNumber = int(file[len(singleEpisodeRegex):len(singleEpisodeRegex)+2])
|
|
||||||
|
|
||||||
folderContents = os.listdir(showDir + file)
|
|
||||||
|
|
||||||
for item in folderContents:
|
|
||||||
if (item[-3:] in subExtensions or item[-3:] in mediaExtensions) and \
|
|
||||||
(episodeNumber in list(range(1, int(episode) + 1))):
|
|
||||||
fileDir = showDir + file + '/' + item
|
|
||||||
print(item)
|
|
||||||
item = removeUploader(item)
|
|
||||||
episodeFolderDir = showDir + show + '/' + show + ' Season ' + season + '/' + \
|
|
||||||
show + ' S' + season + 'E' + '{:02}'.format(episodeNumber) + '/'
|
|
||||||
|
|
||||||
moveEpisode(fileDir, episodeFolderDir + item)
|
|
||||||
|
|
||||||
pprint(os.listdir(showDir + file))
|
|
||||||
if input('Remove contents? [Y/n] ') != 'n':
|
|
||||||
shutil.rmtree(showDir + file)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def parse(show, season, episode):
|
|
||||||
verifyConnectedDirectory()
|
|
||||||
|
|
||||||
show, fuzzyHit = getShowNames(show)
|
|
||||||
if fuzzyHit != 100:
|
|
||||||
if (input('Did you mean:\t' + show + ' [Y/n] ') == 'n'):
|
|
||||||
parse(input('Show query: '), season, episode)
|
|
||||||
exit(0)
|
|
||||||
|
|
||||||
foundSeasons = getSeasons(show)
|
|
||||||
if season not in foundSeasons:
|
|
||||||
if (input('Create season:\t' + season + ' [Y/n] ') == 'n'):
|
|
||||||
exit(0)
|
|
||||||
else:
|
|
||||||
createEpisodeFolders(show, season, episode, True)
|
|
||||||
exit(0)
|
|
||||||
|
|
||||||
createEpisodeFolders(show, season, episode)
|
|
||||||
findStrayEpisodes(show, season, episode)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
print(addShowToDB('Pokemon GO'))
|
|
||||||
exit(0)
|
|
||||||
if argv[-1].endswith('seasonedFolders.py'):
|
|
||||||
findStray()
|
|
||||||
exit(0)
|
|
||||||
|
|
||||||
elif not argv[-1].isdigit() or not argv[-2].isdigit():
|
|
||||||
print(" Missing sesason- or episode number.\nRequired input: [show name] [season nr] [episode nr]")
|
|
||||||
exit(0)
|
|
||||||
show = ' '.join(argv[1:-2])
|
|
||||||
season = '{:02}'.format(int(argv[-2]))
|
|
||||||
episode = '{:02}'.format(int(argv[-1]))
|
|
||||||
|
|
||||||
parse(show, season, episode)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
||||||
Reference in New Issue
Block a user