diff options
author | Adrien Sohier | 2015-06-08 15:29:50 +0200 |
---|---|---|
committer | Adrien Sohier | 2015-06-08 15:29:50 +0200 |
commit | 90ebc1a88410fe3534f18fca0614564d12327514 (patch) | |
tree | 0f70542d1c40e6fb15e8cdc4aba9cbdf7ac6630a | |
download | aur-90ebc1a88410fe3534f18fca0614564d12327514.tar.gz |
init
-rw-r--r-- | .SRCINFO | 19 | ||||
-rw-r--r-- | PKGBUILD | 30 | ||||
-rwxr-xr-x | Trash.py | 170 | ||||
-rw-r--r-- | en.po | 84 | ||||
-rw-r--r-- | fr.po | 76 | ||||
-rw-r--r-- | trash.pot | 75 |
6 files changed, 454 insertions, 0 deletions
diff --git a/.SRCINFO b/.SRCINFO new file mode 100644 index 000000000000..15d5914c9cfa --- /dev/null +++ b/.SRCINFO @@ -0,0 +1,19 @@ +pkgbase = trash-py + pkgdesc = A cli trash in python 3 + pkgver = 1.0 + pkgrel = 1 + url = http://www.art-software.fr + arch = any + license = GPL + depends = coreutils + depends = gettext + depends = python>=3.4 + source = Trash.py + source = en.po + source = fr.po + md5sums = 4ad5337338eeff9f0e0429c151faaad6 + md5sums = ded9fa8a6f295d34b11e852c1cd48062 + md5sums = b1b74c67e04ea5ca142075e8256f562f + +pkgname = trash-py + diff --git a/PKGBUILD b/PKGBUILD new file mode 100644 index 000000000000..ed62d5d45a6a --- /dev/null +++ b/PKGBUILD @@ -0,0 +1,30 @@ +# Maintainer: Adrien Sohier <adrien.sohier@art-software.fr> + +pkgname=trash-py +pkgver=1.0 +pkgrel=1 +pkgdesc='A cli trash in python 3' +arch=('any') +url="http://www.art-software.fr" +license=('GPL') +depends=('coreutils' 'gettext' 'python>=3.4') +source=("Trash.py" + "en.po" + "fr.po") + +md5sums=('4ad5337338eeff9f0e0429c151faaad6' + 'ded9fa8a6f295d34b11e852c1cd48062' + 'b1b74c67e04ea5ca142075e8256f562f') + +build() { + cd "$srcdir" + msgfmt en.po -o en.mo + msgfmt fr.po -o fr.mo +} + +package() { + cd "$srcdir" + install -Dm644 en.mo "$pkgdir/usr/share/locale/en/LC_MESSAGES/trash.mo" + install -Dm644 fr.mo "$pkgdir/usr/share/locale/fr/LC_MESSAGES/trash.mo" + install -Dm755 Trash.py "$pkgdir/usr/bin/trash" +} diff --git a/Trash.py b/Trash.py new file mode 100755 index 000000000000..54b857e3d958 --- /dev/null +++ b/Trash.py @@ -0,0 +1,170 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# vim: foldlevel=0 + +from math import log +from os import environ, listdir, mkdir, stat, unlink +from os.path import basename, dirname, exists, isdir, isfile, islink, realpath +from subprocess import call, getoutput +from sys import argv +from time import localtime, strftime + +import gettext + +gettext.install("trash") + +trashDir = environ["HOME"] + "/.Trash" +dataDir = trashDir + "/files" +pathDir = trashDir + "/path" + +##### Actions ##### +def putToTrash(files): + _id = _getNextId_() + for item in files: + pathItem = "" + + # Get full item path, without following links (ie trash put [link] delete the link, not the link target) + if not islink(item): + pathItem = realpath(item) + else: + if dirname(item) == "": + item = "./" + item + pathItem = realpath(dirname(item)) + "/" + basename(item) + + # FIXME: Find a better way to do this + call(['mv', pathItem, dataDir+"/{itemId}".format(itemId=_id)]) + + # Write metadata + with open(pathDir+"/{itemId}".format(itemId=_id), "w") as f: + f.write("{path}".format(path=pathItem)) + + print(_("Trashed [{itemId}] {path}").format(path=item, itemId=_id)) + _id += 1 + +def listTrash(): + items = [int(i) for i in listdir(pathDir)] + items.sort() + itemLen = len("%d" % max(items+[1])) + print(_("Total size : %s\n") % _trashSize_()[1]) + + for item in items: + with open(pathDir+"/{itemId}".format(itemId=item), "r") as f: + path = f.read().replace("\n", "") + + dataItem = dataDir+"/{itemId}".format(itemId=item) + if exists(dataItem) and not islink(dataItem): + print("\x1B[1;33m%*d: \x1B[0;32m[%s]\x1B[0m %s" % (itemLen, item, strftime("%F %T", localtime(stat(dataDir+"/{itemId}".format(itemId=item)).st_mtime)), path)) + elif islink(dataItem): + print("\x1B[1;33m%*d: \x1B[0;37m[link]\x1B[0m %s" % (itemLen, item, path)) + else: + print("\x1B[1;33m%*d: \x1B[1;31m[invalid]\x1B[0m %s" % (itemLen, item, path)) + +def dropItems(ids): + for item in ids: + path="" + + dataItem = dataDir+"/{itemId}".format(itemId=item) + if not exists(dataItem) and not islink(dataItem): + print(_("ERR: Item #{itemId} was not found in the trash.").format(itemId=item)) + + if isfile(pathDir+"/{itemId}".format(itemId=item)): + with open(pathDir+"/{itemId}".format(itemId=item), "r") as f: + path = f.read().replace("\n", "") + unlink(pathDir+"/{itemId}".format(itemId=item)) + + call(['rm', '-r', '{d}/{item}'.format(d=dataDir, item=item)]) + print(_("Dropped [{itemId}] {itemPath}").format(itemId=item, itemPath=path)) + +def restoreItems(ids): + for item in ids: + path = "" + dataItem = dataDir+"/{itemId}".format(itemId=item) + if not exists(dataItem) and not islink(dataItem): + print(_("ERR: Item #{itemId} was not found in the trash.").format(itemId=item)) + continue + + if isfile(pathDir+"/{itemId}".format(itemId=item)): + with open(pathDir+"/{itemId}".format(itemId=item), "r") as f: + path = f.read().replace("\n", "") + + call(['mv', dataDir+"/{itemId}".format(itemId=item), path]) + unlink(pathDir+"/{itemId}".format(itemId=item)) + print(_("Restored [{itemId}] {itemPath}").format(itemId=item, itemPath=path)) + +def orderIds(): + notFound = 0 + for num, item in enumerate([int(i) for i in listdir(pathDir)]): + print(_("Ordering items… %s") % "|/—\\"[num%4], end="\r") + + dataItem = dataDir+"/{itemId}".format(itemId=item) + if exists(dataItem) or islink(dataItem): + if num+1 != item: + print(_("\rMoved {old} to {new}\x1B[0K").format(old=item, new=num+1)) + call(['mv', dataDir+"/{itemId}".format(itemId=item), dataDir+"/{itemId}".format(itemId=num+1)]) + else: + print(_("\r\x1B[1;31mERR:\x1B[0m Item #{itemId} does not exist under {path}, deleting its metadata\x1B[0K").format(itemId=item, path=dataDir)) + unlink(pathDir+"/{itemId}".format(itemId=item)) + notFound += 1 + if num+1 != item: + call(['mv', pathDir+"/{itemId}".format(itemId=item), pathDir+"/{itemId}".format(itemId=num+1)]) + + if notFound > 0: + print(_("\x1B[1;33mWARNING:\x1B[0m {items} item(s) were not found in {place} and cleaned.").format(items=notFound, place=dataDir)) + +def showHelp(): + print(basename(argv[0])+" [put <path [path [...]]> | list | drop <id [id [...]]> | restore <id [id [...]]> | gc]") + print(_("\n- put:\t\tPut items to trash\n- list:\t\tList trashed items with their id\n- drop:\t\tDrop items from the trash\n- restore:\tRestore items from the trash to their original path\n- gc:\t\tReorder items")) + +##### Useful stuff ##### +def _checkTrashDir_(): + if not isdir(trashDir): + mkdir(trashDir, 0o755) + + if not isdir(dataDir): + mkdir(dataDir, 0o755) + + if not isdir(pathDir): + mkdir(pathDir, 0o755) + +def _trashSize_(): + b = int(getoutput('du -sb {path}/'.format(path=dataDir)).split()[0]) + if b == 0: + return (0, "0 B") + + exp = int(log(b, 1024)) + return (b, "%3.2f %s" % (b/(1024**exp), ["B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB"][exp])) + +def _getNextId_(): + return 1 + max([int(item) for item in listdir(pathDir)]+[0]) + +##### MAIN ##### +if __name__ == "__main__": + args = argv[1:] + _checkTrashDir_() + + while len(args) > 0: + arg = args[0] + args = args[1:] + + if arg == "put": + putToTrash(args) + break + + if arg == "list": + listTrash() + continue + + if arg == "drop": + dropItems(args) + break + + if arg == "restore": + restoreItems(args) + break + + if arg == "gc": + orderIds() + continue + + showHelp() + break diff --git a/en.po b/en.po new file mode 100644 index 000000000000..4f69e795dd48 --- /dev/null +++ b/en.po @@ -0,0 +1,84 @@ +# Trash locale files. +# Copyright (C) 2015, Art SoftWare +# This file is distributed under the GNU GPLv2 or above. +# Adrien Sohier <support@art-software.fr>, 2015. +msgid "" +msgstr "" +"Project-Id-Version: 2.0\n" +"Report-Msgid-Bugs-To: <support@art-software.fr>\n" +"POT-Creation-Date: 2015-06-06 18:18+0200\n" +"PO-Revision-Date: 2015-06-06 18:21+0200\n" +"Last-Translator: <support@art-software.fr>\n" +"Language-Team: English\n" +"Language: en\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: Trash.py:41 +#, python-brace-format +msgid "Trashed [{itemId}] {path}" +msgstr "Trashed [{itemId}] {path}" + +#: Trash.py:48 +#, python-format +msgid "Total size : %s\n" +msgstr "Total size : %s\n" + +#: Trash.py:68 Trash.py:83 +#, python-brace-format +msgid "ERR: Item #{itemId} was not found in the trash." +msgstr "ERR: Item #{itemId} was not found in the trash." + +#: Trash.py:76 +#, python-brace-format +msgid "Dropped [{itemId}] {itemPath}" +msgstr "Dropped [{itemId}] {itemPath}" + +#: Trash.py:92 +#, python-brace-format +msgid "Restored [{itemId}] {itemPath}" +msgstr "Restored [{itemId}] {itemPath}" + +#: Trash.py:97 +#, python-format +msgid "Ordering items… %s" +msgstr "Ordering items… %s" + +#: Trash.py:102 +#, python-brace-format +msgid "\rMoved {old} to {new}[0K" +msgstr "\rMoved {old} to {new}[0K" + +#: Trash.py:105 +#, python-brace-format +msgid "" +"\r[1;31mERR:[0m Item #{itemId} does not exist under {path}, deleting its " +"metadata[0K" +msgstr "" +"\r[1;31mERR:[0m Item #{itemId} does not exist under {path}, deleting its " +"metadata[0K" + +#: Trash.py:112 +#, python-brace-format +msgid "" +"[1;33mWARNING:[0m {items} item(s) were not found in {place} and cleaned." +msgstr "" +"[1;33mWARNING:[0m {items} item(s) were not found in {place} and cleaned." + +#: Trash.py:116 +msgid "" +"\n" +"- put:\t\tPut items to trash\n" +"- list:\t\tList trashed items with their id\n" +"- drop:\t\tDrop items from the trash\n" +"- restore:\tRestore items from the trash to their original path\n" +"- gc:\t\tReorder items" +msgstr "" +"\n" +"- put:\t\tPut items to trash\n" +"- list:\t\tList trashed items with their id\n" +"- drop:\t\tDrop items from the trash\n" +"- restore:\tRestore items from the trash to their original path\n" +"- gc:\t\tReorder items" diff --git a/fr.po b/fr.po new file mode 100644 index 000000000000..caf77d62dd11 --- /dev/null +++ b/fr.po @@ -0,0 +1,76 @@ +# Trash locale files. +# Copyright (C) 2015, Art SoftWare +# This file is distributed under the GNU GPLv2 or above. +# Adrien Sohier <support@art-software.fr>, 2015. +msgid "" +msgstr "" +"Project-Id-Version: 2.0\n" +"Report-Msgid-Bugs-To: <support@art-software.fr>\n" +"POT-Creation-Date: 2015-06-06 18:18+0200\n" +"PO-Revision-Date: 2015-06-06 18:22+0200\n" +"Last-Translator: <support@art-software.fr>\n" +"Language-Team: French\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#: Trash.py:41 +#, python-brace-format +msgid "Trashed [{itemId}] {path}" +msgstr "Déplacé [{itemId}] {path} dans la corbeille" + +#: Trash.py:48 +#, python-format +msgid "Total size : %s\n" +msgstr "Taille totale : %s\n" + +#: Trash.py:68 Trash.py:83 +#, python-brace-format +msgid "ERR: Item #{itemId} was not found in the trash." +msgstr "ERR: L'élément #{itemId} n'a pas été trouvé dans la Corbeille." + +#: Trash.py:76 +#, python-brace-format +msgid "Dropped [{itemId}] {itemPath}" +msgstr "[{itemId}] {itemPath} a été abandonné" + +#: Trash.py:92 +#, python-brace-format +msgid "Restored [{itemId}] {itemPath}" +msgstr "[{itemId}] {itemPath} a été restauré" + +#: Trash.py:97 +#, python-format +msgid "Ordering items… %s" +msgstr "Arrangement des éléments… %s" + +#: Trash.py:102 +#, python-brace-format +msgid "\rMoved {old} to {new}[0K" +msgstr "\rDéplacement de {old} vers {new}[0K" + +#: Trash.py:105 +#, python-brace-format +msgid "\r[1;31mERR:[0m Item #{itemId} does not exist under {path}, deleting its metadata[0K" +msgstr "\r[1;31mERR:[0m L'élément #{itemId} n'existe pas dans {path}, suppression de ses métadonnées[0K" + +#: Trash.py:112 +#, python-brace-format +msgid "[1;33mWARNING:[0m {items} item(s) were not found in {place} and cleaned." +msgstr "[1;33mATTENTION:[0m {items} élément(s) n'ont pas été trouvés dans {place} et nettoyé(s)." + +#: Trash.py:116 +msgid "\n" +"- put:\t\tPut items to trash\n" +"- list:\t\tList trashed items with their id\n" +"- drop:\t\tDrop items from the trash\n" +"- restore:\tRestore items from the trash to their original path\n" +"- gc:\t\tReorder items" +msgstr "\n" +"- put:\t\tMettre les éléments dans la Corbeille\n" +"- list:\t\tListe les éléments mis en Corbeille avec leur numéro identifiant\n" +"- drop:\t\tAbandonne des éléments de la Corbeille\n" +"- restore:\tRestaure des éléments de la Corbeille dans leur emplacement originel\n" +"- gc:\t\tRéorganise les éléments de la Corbeille" diff --git a/trash.pot b/trash.pot new file mode 100644 index 000000000000..bdc73268686d --- /dev/null +++ b/trash.pot @@ -0,0 +1,75 @@ +# Trash locale files. +# Copyright (C) 2015, Art SoftWare +# This file is distributed under the GNU GPLv2 or above. +# Adrien Sohier <support@art-software.fr>, 2015. +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: 2.0\n" +"Report-Msgid-Bugs-To: <support@art-software.fr>\n" +"POT-Creation-Date: 2015-06-06 18:18+0200\n" +"PO-Revision-Date: 2015-06-06 18:20+0200\n" +"Last-Translator: Adrien Sohier <support@art-software.fr>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: Trash.py:41 +#, python-brace-format +msgid "Trashed [{itemId}] {path}" +msgstr "" + +#: Trash.py:48 +#, python-format +msgid "Total size : %s\n" +msgstr "" + +#: Trash.py:68 Trash.py:83 +#, python-brace-format +msgid "ERR: Item #{itemId} was not found in the trash." +msgstr "" + +#: Trash.py:76 +#, python-brace-format +msgid "Dropped [{itemId}] {itemPath}" +msgstr "" + +#: Trash.py:92 +#, python-brace-format +msgid "Restored [{itemId}] {itemPath}" +msgstr "" + +#: Trash.py:97 +#, python-format +msgid "Ordering items… %s" +msgstr "" + +#: Trash.py:102 +#, python-brace-format +msgid "\rMoved {old} to {new}[0K" +msgstr "" + +#: Trash.py:105 +#, python-brace-format +msgid "" +"\r[1;31mERR:[0m Item #{itemId} does not exist under {path}, deleting its " +"metadata[0K" +msgstr "" + +#: Trash.py:112 +#, python-brace-format +msgid "" +"[1;33mWARNING:[0m {items} item(s) were not found in {place} and cleaned." +msgstr "" + +#: Trash.py:116 +msgid "" +"\n" +"- put:\t\tPut items to trash\n" +"- list:\t\tList trashed items with their id\n" +"- drop:\t\tDrop items from the trash\n" +"- restore:\tRestore items from the trash to their original path\n" +"- gc:\t\tReorder items" +msgstr "" |