mirror of
https://github.com/gryf/pygtktalog.git
synced 2025-12-17 11:30:19 +01:00
changes in tests, upgrade to new EXIF module, etc
This commit is contained in:
5
README
5
README
@@ -24,9 +24,8 @@ REQUIREMENTS
|
|||||||
|
|
||||||
pyGTKtalog is written in python with following dependencies:
|
pyGTKtalog is written in python with following dependencies:
|
||||||
|
|
||||||
- python 2.4 or higher
|
- python 2.5 or higher
|
||||||
- pygtk 2.10 or higher <http://www.pygtk.org>
|
- pygtk 2.12 or higher <http://www.pygtk.org>
|
||||||
- pysqlite2 <http://pysqlite.org/> (unnecessary, if python 2.5 is used)
|
|
||||||
|
|
||||||
Optional modules:
|
Optional modules:
|
||||||
|
|
||||||
|
|||||||
121
pygtktalog.py
121
pygtktalog.py
@@ -1,110 +1,62 @@
|
|||||||
# This Python file uses the following encoding: utf-8
|
"""
|
||||||
#
|
Project: pyGTKtalog
|
||||||
# Author: Roman 'gryf' Dobosz gryf@elysium.pl
|
Description: Application main launch file.
|
||||||
#
|
Type: core
|
||||||
# Copyright (C) 2007 by Roman 'gryf' Dobosz
|
Author: Roman 'gryf' Dobosz, gryf73@gmail.com
|
||||||
#
|
Created: 2007-05-01
|
||||||
# This file is part of pyGTKtalog.
|
"""
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation; either version 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software
|
|
||||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
# -------------------------------------------------------------------------
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
try:
|
import locale
|
||||||
import gtk
|
import gettext
|
||||||
except ImportError:
|
|
||||||
print "You need to install pyGTK v2.10.x or newer."
|
|
||||||
raise
|
|
||||||
|
|
||||||
def setup_path():
|
import gtk
|
||||||
"""Sets up the python include paths to include needed directories"""
|
import pygtk
|
||||||
import os.path
|
pygtk.require("2.0")
|
||||||
|
|
||||||
from src.lib.globs import TOPDIR
|
import gtkmvc
|
||||||
sys.path = [os.path.join(TOPDIR, "src")] + sys.path
|
gtkmvc.require("1.2.2")
|
||||||
return
|
|
||||||
|
from src.lib.globs import TOPDIR
|
||||||
|
from src.lib.globs import APPL_SHORT_NAME
|
||||||
|
sys.path = [os.path.join(TOPDIR, "src")] + sys.path
|
||||||
|
from models.m_config import ConfigModel
|
||||||
|
from models.m_main import MainModel
|
||||||
|
from ctrls.c_main import MainController
|
||||||
|
from views.v_main import MainView
|
||||||
|
|
||||||
def check_requirements():
|
def check_requirements():
|
||||||
"""Checks versions and other requirements"""
|
"""Checks versions and other requirements"""
|
||||||
import sys
|
|
||||||
import gtkmvc
|
|
||||||
gtkmvc.require("1.2.0")
|
|
||||||
|
|
||||||
try:
|
|
||||||
from models.m_config import ConfigModel
|
|
||||||
except ImportError:
|
|
||||||
print "Some fundamental files are missing.",
|
|
||||||
print "Try runnig pyGTKtalog in his root directory"
|
|
||||||
raise
|
|
||||||
|
|
||||||
conf = ConfigModel()
|
conf = ConfigModel()
|
||||||
conf.load()
|
conf.load()
|
||||||
|
|
||||||
try:
|
|
||||||
import pygtk
|
|
||||||
#tell pyGTK, if possible, that we want GTKv2
|
|
||||||
pygtk.require("2.0")
|
|
||||||
except ImportError:
|
|
||||||
#Some distributions come with GTK2, but not pyGTK
|
|
||||||
pass
|
|
||||||
|
|
||||||
try:
|
|
||||||
import sqlite3 as sqlite
|
|
||||||
except ImportError:
|
|
||||||
try:
|
|
||||||
from pysqlite2 import dbapi2 as sqlite
|
|
||||||
except ImportError:
|
|
||||||
print "pyGTKtalog uses SQLite DB.\nYou'll need to get it and the",
|
|
||||||
print "python bindings as well.",
|
|
||||||
print "http://www.sqlite.org"
|
|
||||||
print "http://initd.org/tracker/pysqlite"
|
|
||||||
print "Alternatively install python 2.5 or higher"
|
|
||||||
raise
|
|
||||||
|
|
||||||
if conf.confd['exportxls']:
|
|
||||||
try:
|
|
||||||
import pyExcelerator
|
|
||||||
except ImportError:
|
|
||||||
print "WARNING: You'll need pyExcelerator, if you want to export",
|
|
||||||
print "DB to XLS format."
|
|
||||||
print "http://sourceforge.net/projects/pyexcelerator"
|
|
||||||
|
|
||||||
if conf.confd['thumbs'] and conf.confd['retrive']:
|
if conf.confd['thumbs'] and conf.confd['retrive']:
|
||||||
try:
|
try:
|
||||||
import Image
|
import Image
|
||||||
except ImportError:
|
except ImportError:
|
||||||
print "WARNING: You'll need Python Imaging Library (PIL), if you",
|
print _("WARNING: You'll need Python Imaging Library (PIL), if "
|
||||||
print "want to make\nthumbnails!"
|
"you want to make thumbnails!")
|
||||||
|
raise
|
||||||
return
|
return
|
||||||
|
|
||||||
if __name__ == "__main__":
|
def run():
|
||||||
|
"""Create model, controller and view and launch it."""
|
||||||
# Directory from where pygtkatalog was invoced. We need it for calculate
|
# Directory from where pygtkatalog was invoced. We need it for calculate
|
||||||
# path for argument (catalog file)
|
# path for argument (catalog file)
|
||||||
execution_dir = os.path.abspath(os.path.curdir)
|
execution_dir = os.path.abspath(os.path.curdir)
|
||||||
|
|
||||||
# Directory, where this files lies. We need it to setup private source
|
# Directory, where this files lies. We need it to setup private source
|
||||||
# paths
|
# paths
|
||||||
libraries_dir = os.path.dirname(__file__)
|
libraries_dir = os.path.dirname(__file__)
|
||||||
|
if libraries_dir:
|
||||||
os.chdir(libraries_dir)
|
os.chdir(libraries_dir)
|
||||||
|
|
||||||
setup_path()
|
# Setup i18n
|
||||||
#check_requirements()
|
locale.setlocale(locale.LC_ALL, '')
|
||||||
|
gettext.install(APPL_SHORT_NAME, 'locale', unicode=True)
|
||||||
|
|
||||||
from models.m_main import MainModel
|
check_requirements()
|
||||||
from ctrls.c_main import MainController
|
|
||||||
from views.v_main import MainView
|
|
||||||
|
|
||||||
model = MainModel()
|
model = MainModel()
|
||||||
if len(sys.argv) > 1:
|
if len(sys.argv) > 1:
|
||||||
@@ -115,6 +67,9 @@ if __name__ == "__main__":
|
|||||||
try:
|
try:
|
||||||
gtk.main()
|
gtk.main()
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
#model.config.save()
|
model.config.save()
|
||||||
#model.cleanup()
|
model.cleanup()
|
||||||
gtk.main_quit
|
gtk.main_quit
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
run()
|
||||||
|
|||||||
@@ -252,7 +252,7 @@ class MainController(Controller):
|
|||||||
except TypeError:
|
except TypeError:
|
||||||
if __debug__:
|
if __debug__:
|
||||||
print "c_main.py: on_edit2_activate(): 0",
|
print "c_main.py: on_edit2_activate(): 0",
|
||||||
print "zaznaczonych wierszy"
|
print "selected rows"
|
||||||
return
|
return
|
||||||
|
|
||||||
val = self.model.get_file_info(id)
|
val = self.model.get_file_info(id)
|
||||||
@@ -281,11 +281,9 @@ class MainController(Controller):
|
|||||||
|
|
||||||
def on_remove_thumb1_activate(self, menu_item):
|
def on_remove_thumb1_activate(self, menu_item):
|
||||||
if self.model.config.confd['delwarn']:
|
if self.model.config.confd['delwarn']:
|
||||||
title = 'Delete thumbnails'
|
obj = Dialogs.Qst(_("Delete thumbnails"), _("Delete thumbnails?"),
|
||||||
question = 'Delete thumbnails?'
|
_("Thumbnails for selected items will be "
|
||||||
description = "Thumbnails for selected items will be permanently"
|
"permanently removed from catalog."))
|
||||||
description += " removed from catalog."
|
|
||||||
obj = Dialogs.Qst(title, question, description)
|
|
||||||
if not obj.run():
|
if not obj.run():
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
@@ -307,11 +305,9 @@ class MainController(Controller):
|
|||||||
|
|
||||||
def on_remove_image1_activate(self, menu_item):
|
def on_remove_image1_activate(self, menu_item):
|
||||||
if self.model.config.confd['delwarn']:
|
if self.model.config.confd['delwarn']:
|
||||||
title = 'Delete images'
|
obj = Dialogs.Qst(_("Delete images"), _("Delete all images?"),
|
||||||
question = 'Delete all images?'
|
_("All images for selected items will be "
|
||||||
description = 'All images for selected items will be permanently'
|
"permanently removed from catalog."))
|
||||||
description += ' removed from catalog.'
|
|
||||||
obj = Dialogs.Qst(title, question, description)
|
|
||||||
if not obj.run():
|
if not obj.run():
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
@@ -343,8 +339,8 @@ class MainController(Controller):
|
|||||||
else:
|
else:
|
||||||
ImageView(img)
|
ImageView(img)
|
||||||
else:
|
else:
|
||||||
Dialogs.Inf("Image view", "No Image",
|
Dialogs.Inf(_("Image view"), _("No Image"),
|
||||||
"Image file does not exist.")
|
_("Image file does not exist."))
|
||||||
|
|
||||||
def on_rename1_activate(self, widget):
|
def on_rename1_activate(self, widget):
|
||||||
model, iter = self.view['discs'].get_selection().get_selected()
|
model, iter = self.view['discs'].get_selection().get_selected()
|
||||||
@@ -492,11 +488,10 @@ class MainController(Controller):
|
|||||||
# check if any unsaved project is on go.
|
# check if any unsaved project is on go.
|
||||||
if self.model.unsaved_project and \
|
if self.model.unsaved_project and \
|
||||||
self.model.config.confd['confirmquit']:
|
self.model.config.confd['confirmquit']:
|
||||||
title = 'Quit application - pyGTKtalog'
|
if not Dialogs.Qst(_("Quit application") + " - pyGTKtalog",
|
||||||
question = 'Do you really want to quit?'
|
_("Do you really want to quit?"),
|
||||||
description = "Current database is not saved, any changes will "
|
_("Current database is not saved, any changes "
|
||||||
description += "be lost."
|
"will be lost.")).run():
|
||||||
if not Dialogs.Qst(title, question, description).run():
|
|
||||||
return
|
return
|
||||||
self.__store_settings()
|
self.__store_settings()
|
||||||
self.model.cleanup()
|
self.model.cleanup()
|
||||||
@@ -506,10 +501,10 @@ class MainController(Controller):
|
|||||||
def on_new_activate(self, widget):
|
def on_new_activate(self, widget):
|
||||||
"""Create new database file"""
|
"""Create new database file"""
|
||||||
if self.model.unsaved_project:
|
if self.model.unsaved_project:
|
||||||
title = 'Unsaved data - pyGTKtalog'
|
if not Dialogs.Qst(_("Unsaved data") + " - pyGTKtalog",
|
||||||
question = "Do you want to abandon changes?"
|
_("Do you want to abandon changes?"),
|
||||||
desc = "Current database is not saved, any changes will be lost."
|
_("Current database is not saved, any changes "
|
||||||
if not Dialogs.Qst(title, question, desc).run():
|
"will be lost.")).run():
|
||||||
return
|
return
|
||||||
self.model.new()
|
self.model.new()
|
||||||
|
|
||||||
@@ -525,8 +520,8 @@ class MainController(Controller):
|
|||||||
|
|
||||||
def on_add_cd_activate(self, widget, label=None, current_id=None):
|
def on_add_cd_activate(self, widget, label=None, current_id=None):
|
||||||
"""Add directory structure from cd/dvd disc"""
|
"""Add directory structure from cd/dvd disc"""
|
||||||
mount = device_helper.volmount(self.model.config.confd['cd'])
|
mount, msg = device_helper.volmount(self.model.config.confd['cd'])
|
||||||
if mount == 'ok':
|
if mount:
|
||||||
guessed_label = device_helper.volname(self.model.config.confd['cd'])
|
guessed_label = device_helper.volname(self.model.config.confd['cd'])
|
||||||
if not label:
|
if not label:
|
||||||
label = Dialogs.InputDiskLabel(guessed_label).run()
|
label = Dialogs.InputDiskLabel(guessed_label).run()
|
||||||
@@ -543,10 +538,10 @@ class MainController(Controller):
|
|||||||
device_helper.volumount(self.model.config.confd['cd'])
|
device_helper.volumount(self.model.config.confd['cd'])
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
Dialogs.Wrn("Error mounting device - pyGTKtalog",
|
Dialogs.Wrn(_("Error mounting device") + " - pyGTKtalog",
|
||||||
"Cannot mount device pointed to %s" %
|
_("Cannot mount device pointed to %s") %
|
||||||
self.model.config.confd['cd'],
|
self.model.config.confd['cd'],
|
||||||
"Last mount message:\n%s" % mount)
|
_("Last mount message:\n%s") % msg)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def on_add_directory_activate(self, widget, path=None, label=None,
|
def on_add_directory_activate(self, widget, path=None, label=None,
|
||||||
@@ -599,6 +594,7 @@ class MainController(Controller):
|
|||||||
|
|
||||||
def on_save_activate(self, widget):
|
def on_save_activate(self, widget):
|
||||||
"""Save catalog to file"""
|
"""Save catalog to file"""
|
||||||
|
# FIXME: Traceback when recent is null
|
||||||
if self.model.filename:
|
if self.model.filename:
|
||||||
self.model.save()
|
self.model.save()
|
||||||
self.__set_title(filepath=self.model.filename)
|
self.__set_title(filepath=self.model.filename)
|
||||||
@@ -618,8 +614,8 @@ class MainController(Controller):
|
|||||||
self.model.config.add_recent(path)
|
self.model.config.add_recent(path)
|
||||||
self.__set_title(filepath=path)
|
self.__set_title(filepath=path)
|
||||||
else:
|
else:
|
||||||
Dialogs.Err("Error writing file - pyGTKtalog",
|
Dialogs.Err(_("Error writing file") + " - pyGTKtalog",
|
||||||
"Cannot write file %s." % path, "%s" % err)
|
_("Cannot write file %s.") % path, "%s" % err)
|
||||||
|
|
||||||
def on_stat1_activate(self, menu_item, selected_id=None):
|
def on_stat1_activate(self, menu_item, selected_id=None):
|
||||||
data = self.model.get_stats(selected_id)
|
data = self.model.get_stats(selected_id)
|
||||||
@@ -640,9 +636,9 @@ class MainController(Controller):
|
|||||||
"""Open catalog file"""
|
"""Open catalog file"""
|
||||||
confirm = self.model.config.confd['confirmabandon']
|
confirm = self.model.config.confd['confirmabandon']
|
||||||
if self.model.unsaved_project and confirm:
|
if self.model.unsaved_project and confirm:
|
||||||
obj = Dialogs.Qst('Unsaved data - pyGTKtalog',
|
obj = Dialogs.Qst(_("Unsaved data") + " - pyGTKtalog",
|
||||||
'There is not saved database',
|
_("There is not saved database"),
|
||||||
'Pressing "Ok" will abandon catalog.')
|
_("Pressing <b>Ok</b> will abandon catalog."))
|
||||||
if not obj.run():
|
if not obj.run():
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -666,8 +662,8 @@ class MainController(Controller):
|
|||||||
|
|
||||||
if path:
|
if path:
|
||||||
if not self.model.open(path):
|
if not self.model.open(path):
|
||||||
Dialogs.Err("Error opening file - pyGTKtalog",
|
Dialogs.Err(_("Error opening file") + " - pyGTKtalog",
|
||||||
"Cannot open file %s." % path)
|
_("Cannot open file %s.") % path)
|
||||||
else:
|
else:
|
||||||
self.__generate_recent_menu()
|
self.__generate_recent_menu()
|
||||||
self.__activate_ui(path)
|
self.__activate_ui(path)
|
||||||
@@ -733,13 +729,14 @@ class MainController(Controller):
|
|||||||
"""delete selected images (with thumbnails)"""
|
"""delete selected images (with thumbnails)"""
|
||||||
list_of_paths = self.view['images'].get_selected_items()
|
list_of_paths = self.view['images'].get_selected_items()
|
||||||
if not list_of_paths:
|
if not list_of_paths:
|
||||||
Dialogs.Inf("Delete images", "No images selected",
|
Dialogs.Inf(_("Delete images"), _("No images selected"),
|
||||||
"You have to select at least one image to delete.")
|
_("You have to select at least one image to delete."))
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.model.config.confd['delwarn']:
|
if self.model.config.confd['delwarn']:
|
||||||
obj = Dialogs.Qst('Delete images', 'Delete selected images?',
|
obj = Dialogs.Qst(_("Delete images"), _("Delete selected images?"),
|
||||||
'Selected images will be permanently removed from catalog.')
|
_("Selected images will be permanently removed"
|
||||||
|
" from catalog."))
|
||||||
if not obj.run():
|
if not obj.run():
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -768,7 +765,7 @@ class MainController(Controller):
|
|||||||
|
|
||||||
def on_img_save_activate(self, menu_item):
|
def on_img_save_activate(self, menu_item):
|
||||||
"""export images (not thumbnails) into desired direcotry"""
|
"""export images (not thumbnails) into desired direcotry"""
|
||||||
dialog = Dialogs.SelectDirectory("Choose directory to save images")
|
dialog = Dialogs.SelectDirectory(_("Choose directory to save images"))
|
||||||
filepath = dialog.run()
|
filepath = dialog.run()
|
||||||
|
|
||||||
if not filepath:
|
if not filepath:
|
||||||
@@ -793,14 +790,13 @@ class MainController(Controller):
|
|||||||
count += 1
|
count += 1
|
||||||
|
|
||||||
if count > 0:
|
if count > 0:
|
||||||
Dialogs.Inf("Save images",
|
Dialogs.Inf(_("Save images"),
|
||||||
"%d images was succsefully saved." % count,
|
_("%d images was succsefully saved.") % count,
|
||||||
"Images are placed in directory:\n%s." % filepath)
|
_("Images are placed in directory:\n%s.") % filepath)
|
||||||
else:
|
else:
|
||||||
description = "Images probably don't have real images - only"
|
description = _("Images probably don't have real images - only"
|
||||||
description += " thumbnails."
|
" thumbnails.")
|
||||||
Dialogs.Inf("Save images",
|
Dialogs.Inf(_("Save images"), _("No images was saved."),
|
||||||
"No images was saved.",
|
|
||||||
description)
|
description)
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -809,12 +805,12 @@ class MainController(Controller):
|
|||||||
list_of_paths = self.view['images'].get_selected_items()
|
list_of_paths = self.view['images'].get_selected_items()
|
||||||
|
|
||||||
if not list_of_paths:
|
if not list_of_paths:
|
||||||
Dialogs.Inf("Set thumbnail", "No image selected",
|
Dialogs.Inf(_("Set thumbnail"), _("No image selected"),
|
||||||
"You have to select one image to set as thumbnail.")
|
_("You have to select one image to set as thumbnail."))
|
||||||
return
|
return
|
||||||
if len(list_of_paths) >1:
|
if len(list_of_paths) >1:
|
||||||
Dialogs.Inf("Set thumbnail", "To many images selected",
|
Dialogs.Inf(_("Set thumbnail"), _("To many images selected"),
|
||||||
"You have to select one image to set as thumbnail.")
|
_("You have to select one image to set as thumbnail."))
|
||||||
return
|
return
|
||||||
|
|
||||||
model = self.view['images'].get_model()
|
model = self.view['images'].get_model()
|
||||||
@@ -872,7 +868,7 @@ class MainController(Controller):
|
|||||||
|
|
||||||
def on_export_activate(self, menu_item):
|
def on_export_activate(self, menu_item):
|
||||||
"""export db file and coressponding images to tar.bz2 archive"""
|
"""export db file and coressponding images to tar.bz2 archive"""
|
||||||
dialog = Dialogs.ChooseFilename(None, "Choose export file")
|
dialog = Dialogs.ChooseFilename(None, _("Choose export file"))
|
||||||
filepath = dialog.run()
|
filepath = dialog.run()
|
||||||
|
|
||||||
if not filepath:
|
if not filepath:
|
||||||
@@ -1018,8 +1014,8 @@ class MainController(Controller):
|
|||||||
def on_delete_tag_activate(self, menu_item):
|
def on_delete_tag_activate(self, menu_item):
|
||||||
ids = self.__get_tv_selection_ids(self.view['files'])
|
ids = self.__get_tv_selection_ids(self.view['files'])
|
||||||
if not ids:
|
if not ids:
|
||||||
Dialogs.Inf("Remove tags", "No files selected",
|
Dialogs.Inf(_("Remove tags"), _("No files selected"),
|
||||||
"You have to select some files first.")
|
_("You have to select some files first."))
|
||||||
return
|
return
|
||||||
|
|
||||||
tags = self.model.get_tags_by_file_id(ids)
|
tags = self.model.get_tags_by_file_id(ids)
|
||||||
@@ -1027,8 +1023,9 @@ class MainController(Controller):
|
|||||||
d = Dialogs.TagsRemoveDialog(tags)
|
d = Dialogs.TagsRemoveDialog(tags)
|
||||||
retcode, retval = d.run()
|
retcode, retval = d.run()
|
||||||
if retcode=="ok" and not retval:
|
if retcode=="ok" and not retval:
|
||||||
Dialogs.Inf("Remove tags", "No tags selected",
|
Dialogs.Inf(_("Remove tags"), _("No tags selected"),
|
||||||
"You have to select any tag to remove from files.")
|
_("You have to select any tag to remove from"
|
||||||
|
" files."))
|
||||||
return
|
return
|
||||||
elif retcode == "ok" and retval:
|
elif retcode == "ok" and retval:
|
||||||
self.model.delete_tags(ids, retval)
|
self.model.delete_tags(ids, retval)
|
||||||
@@ -1053,7 +1050,7 @@ class MainController(Controller):
|
|||||||
|
|
||||||
def on_add_image1_activate(self, menu_item):
|
def on_add_image1_activate(self, menu_item):
|
||||||
dialog = Dialogs.LoadImageFile(True)
|
dialog = Dialogs.LoadImageFile(True)
|
||||||
msg = "Don't copy images. Generate only thumbnails."
|
msg = _("Don't copy images. Generate only thumbnails.")
|
||||||
toggle = gtk.CheckButton(msg)
|
toggle = gtk.CheckButton(msg)
|
||||||
toggle.show()
|
toggle.show()
|
||||||
dialog.dialog.set_extra_widget(toggle)
|
dialog.dialog.set_extra_widget(toggle)
|
||||||
@@ -1117,15 +1114,15 @@ class MainController(Controller):
|
|||||||
return
|
return
|
||||||
|
|
||||||
if not selected_iter:
|
if not selected_iter:
|
||||||
Dialogs.Inf("Delete disc", "No disc selected",
|
Dialogs.Inf(_("Delete disc"), _("No disc selected"),
|
||||||
"You have to select disc first before you " +\
|
_("You have to select disc first before you "
|
||||||
"can delete it")
|
"can delete it"))
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.model.config.confd['delwarn']:
|
if self.model.config.confd['delwarn']:
|
||||||
name = model.get_value(selected_iter, 1)
|
name = model.get_value(selected_iter, 1)
|
||||||
obj = Dialogs.Qst('Delete %s' % name, 'Delete %s?' % name,
|
obj = Dialogs.Qst(_("Delete %s") % name, _("Delete %s?") % name,
|
||||||
'Object will be permanently removed.')
|
_("Object will be permanently removed."))
|
||||||
if not obj.run():
|
if not obj.run():
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -1168,14 +1165,14 @@ class MainController(Controller):
|
|||||||
return
|
return
|
||||||
|
|
||||||
if not list_of_paths:
|
if not list_of_paths:
|
||||||
Dialogs.Inf("Delete files", "No files selected",
|
Dialogs.Inf(_("Delete files"), _("No files selected"),
|
||||||
"You have to select at least one file to delete.")
|
_("You have to select at least one file to delete."))
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.model.config.confd['delwarn']:
|
if self.model.config.confd['delwarn']:
|
||||||
description = "Selected files and directories will be "
|
obj = Dialogs.Qst(_("Delete files"), _("Delete files?"),
|
||||||
description += "permanently\n removed from catalog."
|
_("Selected files and directories will be "
|
||||||
obj = Dialogs.Qst("Delete files", "Delete files?", description)
|
"permanently\n removed from catalog."))
|
||||||
if not obj.run():
|
if not obj.run():
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -1216,10 +1213,9 @@ class MainController(Controller):
|
|||||||
|
|
||||||
def on_th_delete_activate(self, menu_item):
|
def on_th_delete_activate(self, menu_item):
|
||||||
if self.model.config.confd['delwarn']:
|
if self.model.config.confd['delwarn']:
|
||||||
title = 'Delete thumbnail'
|
obj = Dialogs.Qst(_("Delete thumbnail"), _("Delete thumbnail?"),
|
||||||
question = 'Delete thumbnail?'
|
_("Current thumbnail will be permanently removed"
|
||||||
dsc = "Current thumbnail will be permanently removed from catalog."
|
" from catalog."))
|
||||||
obj = Dialogs.Qst(title, question, dsc)
|
|
||||||
if not obj.run():
|
if not obj.run():
|
||||||
return
|
return
|
||||||
path, column = self.view['files'].get_cursor()
|
path, column = self.view['files'].get_cursor()
|
||||||
@@ -1366,17 +1362,19 @@ class MainController(Controller):
|
|||||||
msg = device_helper.eject_cd(ejectapp,
|
msg = device_helper.eject_cd(ejectapp,
|
||||||
self.model.config.confd['cd'])
|
self.model.config.confd['cd'])
|
||||||
if msg != 'ok':
|
if msg != 'ok':
|
||||||
Dialogs.Wrn("error ejecting device - pyGTKtalog",
|
title = _("Error ejecting device")
|
||||||
"Cannot eject device pointed to %s" %
|
Dialogs.Wrn(title + " - pyGTKtalog",
|
||||||
|
_("Cannot eject device pointed to %s") %
|
||||||
self.model.config.confd['cd'],
|
self.model.config.confd['cd'],
|
||||||
"Last eject message:\n%s" % msg)
|
_("Last eject message:\n%s") % msg)
|
||||||
else:
|
else:
|
||||||
msg = device_helper.volumount(self.model.config.confd['cd'])
|
msg = device_helper.volumount(self.model.config.confd['cd'])
|
||||||
if msg != 'ok':
|
if msg != 'ok':
|
||||||
Dialogs.Wrn("error unmounting device - pyGTKtalog",
|
title = _("Error unmounting device")
|
||||||
"Cannot unmount device pointed to %s" %
|
Dialogs.Wrn(title + " - pyGTKtalog",
|
||||||
|
_("Cannot unmount device pointed to %s") %
|
||||||
self.model.config.confd['cd'],
|
self.model.config.confd['cd'],
|
||||||
"Last umount message:\n%s" % msg)
|
_("Last umount message:\n%s") % msg)
|
||||||
return
|
return
|
||||||
|
|
||||||
def property_progress_value_change(self, model, old, new):
|
def property_progress_value_change(self, model, old, new):
|
||||||
|
|||||||
1209
src/lib/EXIF.py
1209
src/lib/EXIF.py
File diff suppressed because it is too large
Load Diff
@@ -1,32 +1,23 @@
|
|||||||
# This Python file uses the following encoding: utf-8
|
"""
|
||||||
#
|
Project: pyGTKtalog
|
||||||
# Author: Roman 'gryf' Dobosz gryf@elysium.pl
|
Description: Simple functions for device management.
|
||||||
#
|
Type: lib
|
||||||
# Copyright (C) 2007 by Roman 'gryf' Dobosz
|
Author: Roman 'gryf' Dobosz, gryf73@gmail.com
|
||||||
#
|
Created: 2008-12-15
|
||||||
# This file is part of pyGTKtalog.
|
"""
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation; either version 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software
|
|
||||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
# -------------------------------------------------------------------------
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import locale
|
||||||
|
import gettext
|
||||||
|
|
||||||
|
from src.lib.globs import APPL_SHORT_NAME
|
||||||
|
|
||||||
|
locale.setlocale(locale.LC_ALL, '')
|
||||||
|
gettext.install(APPL_SHORT_NAME, 'locale', unicode=True)
|
||||||
|
|
||||||
def volname(mntp):
|
def volname(mntp):
|
||||||
"""read volume name from cd/dvd"""
|
"""read volume name from cd/dvd"""
|
||||||
dev = mountpoint_to_dev(mntp)
|
dev = mountpoint_to_dev(mntp)
|
||||||
|
label = None
|
||||||
if dev != None:
|
if dev != None:
|
||||||
try:
|
try:
|
||||||
disk = open(dev, "rb")
|
disk = open(dev, "rb")
|
||||||
@@ -36,16 +27,19 @@ def volname(mntp):
|
|||||||
except IOError:
|
except IOError:
|
||||||
return None
|
return None
|
||||||
return label
|
return label
|
||||||
return None
|
|
||||||
|
|
||||||
def volmount(mntp):
|
def volmount(mntp):
|
||||||
"""mount device, return 'ok' or error message"""
|
"""
|
||||||
|
Mount device.
|
||||||
|
@param mountpoint
|
||||||
|
@returns tuple with bool status of mount, and string with error message
|
||||||
|
"""
|
||||||
_in, _out, _err = os.popen3("mount %s" % mntp)
|
_in, _out, _err = os.popen3("mount %s" % mntp)
|
||||||
inf = _err.readlines()
|
inf = _err.readlines()
|
||||||
if len(inf) > 0:
|
if len(inf) > 0:
|
||||||
return inf[0].strip()
|
return False, inf[0].strip()
|
||||||
else:
|
else:
|
||||||
return 'ok'
|
return True, ''
|
||||||
|
|
||||||
def volumount(mntp):
|
def volumount(mntp):
|
||||||
"""mount device, return 'ok' or error message"""
|
"""mount device, return 'ok' or error message"""
|
||||||
@@ -88,5 +82,5 @@ def eject_cd(eject_app, cdrom):
|
|||||||
return inf[0].strip()
|
return inf[0].strip()
|
||||||
|
|
||||||
return 'ok'
|
return 'ok'
|
||||||
return "Eject program not specified"
|
return _("Eject program not specified")
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ TOPDIR = top_dir
|
|||||||
RESOURCES_DIR = os.path.join(TOPDIR, "resources")
|
RESOURCES_DIR = os.path.join(TOPDIR, "resources")
|
||||||
GLADE_DIR = os.path.join(RESOURCES_DIR, "glade")
|
GLADE_DIR = os.path.join(RESOURCES_DIR, "glade")
|
||||||
STYLES_DIR = os.path.join(RESOURCES_DIR, "styles")
|
STYLES_DIR = os.path.join(RESOURCES_DIR, "styles")
|
||||||
APPL_SHORT_NAME = "pygtktalog2"
|
APPL_SHORT_NAME = "pygtktalog"
|
||||||
APPL_VERSION = (1, 0, 2)
|
APPL_VERSION = (1, 0, 2)
|
||||||
# ----------------------------------------------------------------------
|
# ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ import os
|
|||||||
from datetime import date
|
from datetime import date
|
||||||
|
|
||||||
class GthumbCommentParser(object):
|
class GthumbCommentParser(object):
|
||||||
|
"""Read and return comments created eith gThumb program"""
|
||||||
def __init__(self, image_path, image_filename):
|
def __init__(self, image_path, image_filename):
|
||||||
self.path = image_path
|
self.path = image_path
|
||||||
self.filename = image_filename
|
self.filename = image_filename
|
||||||
@@ -36,16 +36,16 @@ class GthumbCommentParser(object):
|
|||||||
"""Return dictionary with apropriate fields, or None if no comment
|
"""Return dictionary with apropriate fields, or None if no comment
|
||||||
available"""
|
available"""
|
||||||
try:
|
try:
|
||||||
gf = gzip.open(os.path.join(self.path,
|
gzf = gzip.open(os.path.join(self.path, '.comments',
|
||||||
'.comments', self.filename + '.xml'))
|
self.filename + '.xml'))
|
||||||
except:
|
except:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
xml = gf.read()
|
xml = gzf.read()
|
||||||
gf.close()
|
gzf.close()
|
||||||
except:
|
except:
|
||||||
gf.close()
|
gzf.close()
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if not xml:
|
if not xml:
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ class Img(object):
|
|||||||
"""Save image and asociated thumbnail into specific directory structure
|
"""Save image and asociated thumbnail into specific directory structure
|
||||||
returns filename for image"""
|
returns filename for image"""
|
||||||
|
|
||||||
|
|
||||||
image_filename = path.join(self.base, self.sha512)
|
image_filename = path.join(self.base, self.sha512)
|
||||||
thumbnail = path.join(self.base, self.sha512 + "_t")
|
thumbnail = path.join(self.base, self.sha512 + "_t")
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
# This Python file uses the following encoding: utf-8
|
"""
|
||||||
|
Project: pyGTKtalog
|
||||||
|
Description: Gather video file information. Uses external tools.
|
||||||
|
Type: lib
|
||||||
|
Author: Roman 'gryf' Dobosz, gryf73@gmail.com
|
||||||
|
Created: 2008-12-15
|
||||||
|
"""
|
||||||
from os import popen
|
from os import popen
|
||||||
from sys import argv, exit
|
import sys
|
||||||
|
|
||||||
class Midentify(object):
|
class Midentify(object):
|
||||||
"""Class for retrive midentify script output and put it in dict.
|
"""Class for retrive midentify script output and put it in dict.
|
||||||
@@ -16,48 +21,41 @@ class Midentify(object):
|
|||||||
|
|
||||||
def get_data(self):
|
def get_data(self):
|
||||||
"""return dict with clip information"""
|
"""return dict with clip information"""
|
||||||
output = popen("midentify \"%s\"" % self.filename).readlines()
|
output = popen('midentify "%s"' % self.filename).readlines()
|
||||||
|
|
||||||
|
attrs = {'ID_VIDEO_WIDTH': ['width', int],
|
||||||
|
'ID_VIDEO_HEIGHT': ['height', int],
|
||||||
|
'ID_LENGTH': ['length', lambda x: int(x.split(".")[0])],
|
||||||
|
# length is in seconds
|
||||||
|
'ID_DEMUXER': ['container', str],
|
||||||
|
'ID_VIDEO_FORMAT': ['video_format', str],
|
||||||
|
'ID_VIDEO_CODEC': ['video_codec', str],
|
||||||
|
'ID_AUDIO_CODEC': ['audio_codec', str],
|
||||||
|
'ID_AUDIO_FORMAT': ['audio_format', str],
|
||||||
|
'ID_AUDIO_NCH': ['audio_no_channels', int],}
|
||||||
|
|
||||||
for line in output:
|
for line in output:
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
if "ID_VIDEO_WIDTH" in line:
|
for attr in attrs:
|
||||||
self.tags['width'] = line.replace("ID_VIDEO_WIDTH=", "")
|
if attr in line:
|
||||||
elif "ID_VIDEO_HEIGHT" in line:
|
self.tags[attrs[attr][0]] = \
|
||||||
self.tags['height'] = line.replace("ID_VIDEO_HEIGHT=", "")
|
attrs[attr][1](line.replace("%s=" % attr, ""))
|
||||||
elif "ID_LENGTH" in line:
|
|
||||||
length = line.replace("ID_LENGTH=", "")
|
if 'length' in self.tags:
|
||||||
if "." in length:
|
if self.tags['length'] > 0:
|
||||||
length = length.split(".")[0]
|
hours = self.tags['length'] / 3600
|
||||||
seconds = int(length)
|
seconds = self.tags['length'] - hours * 3600
|
||||||
if seconds > 0:
|
|
||||||
hours = seconds / 3600
|
|
||||||
seconds -= hours * 3600
|
|
||||||
minutes = seconds / 60
|
minutes = seconds / 60
|
||||||
seconds -= minutes * 60
|
seconds -= minutes * 60
|
||||||
self.tags['length'] = length
|
|
||||||
length_str = "%02d:%02d:%02d" % (hours, minutes, seconds)
|
length_str = "%02d:%02d:%02d" % (hours, minutes, seconds)
|
||||||
self.tags['duration'] = length_str
|
self.tags['duration'] = length_str
|
||||||
elif "ID_DEMUXER" in line:
|
|
||||||
self.tags['container'] = line.replace("ID_DEMUXER=", "")
|
|
||||||
elif "ID_VIDEO_FORMAT" in line:
|
|
||||||
self.tags['video_format'] = line.replace("ID_VIDEO_FORMAT=", "")
|
|
||||||
elif "ID_VIDEO_CODEC" in line:
|
|
||||||
self.tags['video_codec'] = line.replace("ID_VIDEO_CODEC=", "")
|
|
||||||
elif "ID_AUDIO_CODEC" in line:
|
|
||||||
self.tags['audio_codec'] = line.replace("ID_AUDIO_CODEC=", "")
|
|
||||||
elif "ID_AUDIO_FORMAT" in line:
|
|
||||||
self.tags['audio_format'] = line.replace("ID_AUDIO_FORMAT=", "")
|
|
||||||
elif "ID_AUDIO_NCH" in line:
|
|
||||||
self.tags['audio_no_channels'] = line.replace("ID_AUDIO_NCH=",
|
|
||||||
"")
|
|
||||||
return self.tags
|
return self.tags
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
"""run as standalone script"""
|
if len(sys.argv) < 2:
|
||||||
if len(argv) < 2:
|
print "usage: %s filename" % sys.argv[0]
|
||||||
print "usage: %s filename" % argv[0]
|
sys.exit()
|
||||||
exit()
|
|
||||||
|
|
||||||
for arg in argv[1:]:
|
for arg in sys.argv[1:]:
|
||||||
mid = Midentify(arg)
|
mid = Midentify(arg)
|
||||||
print mid.get_data()
|
print mid.get_data()
|
||||||
|
|||||||
@@ -27,23 +27,17 @@ import sys
|
|||||||
import shutil
|
import shutil
|
||||||
import bz2
|
import bz2
|
||||||
import math
|
import math
|
||||||
|
import sqlite3 as sqlite
|
||||||
from tempfile import mkstemp
|
from tempfile import mkstemp
|
||||||
|
from datetime import datetime
|
||||||
|
import threading as _threading
|
||||||
|
|
||||||
import gtk
|
import gtk
|
||||||
import gobject
|
import gobject
|
||||||
|
|
||||||
from gtkmvc.model_mt import ModelMT
|
from gtkmvc.model_mt import ModelMT
|
||||||
|
|
||||||
try:
|
|
||||||
import sqlite3 as sqlite
|
|
||||||
except ImportError:
|
|
||||||
from pysqlite2 import dbapi2 as sqlite
|
|
||||||
|
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
import threading as _threading
|
|
||||||
|
|
||||||
from m_config import ConfigModel
|
from m_config import ConfigModel
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from lib.thumbnail import Thumbnail
|
from lib.thumbnail import Thumbnail
|
||||||
from lib.img import Img
|
from lib.img import Img
|
||||||
@@ -53,6 +47,7 @@ from lib.parse_exif import ParseExif
|
|||||||
from lib.gthumb import GthumbCommentParser
|
from lib.gthumb import GthumbCommentParser
|
||||||
|
|
||||||
from lib.no_thumb import no_thumb as no_thumb_img
|
from lib.no_thumb import no_thumb as no_thumb_img
|
||||||
|
from lib.video import Video
|
||||||
|
|
||||||
class MainModel(ModelMT):
|
class MainModel(ModelMT):
|
||||||
"""Create, load, save, manipulate db file which is container for data"""
|
"""Create, load, save, manipulate db file which is container for data"""
|
||||||
@@ -91,6 +86,7 @@ class MainModel(ModelMT):
|
|||||||
# images extensions - only for PIL and EXIF
|
# images extensions - only for PIL and EXIF
|
||||||
IMG = ['jpg', 'jpeg', 'gif', 'png', 'tif', 'tiff', 'tga', 'pcx', 'bmp',
|
IMG = ['jpg', 'jpeg', 'gif', 'png', 'tif', 'tiff', 'tga', 'pcx', 'bmp',
|
||||||
'xbm', 'xpm', 'jp2', 'jpx', 'pnm']
|
'xbm', 'xpm', 'jp2', 'jpx', 'pnm']
|
||||||
|
MOV = ['avi', 'mpg', 'mpeg', 'mkv', 'wmv', 'ogm', 'mov']
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
"""initialize"""
|
"""initialize"""
|
||||||
@@ -1754,6 +1750,23 @@ class MainModel(ModelMT):
|
|||||||
|
|
||||||
ext = i.split('.')[-1].lower()
|
ext = i.split('.')[-1].lower()
|
||||||
|
|
||||||
|
# Video
|
||||||
|
if ext in self.MOV:
|
||||||
|
#import rpdb2; rpdb2.start_embedded_debugger('pass')
|
||||||
|
v = Video(current_file)
|
||||||
|
cfn = v.capture()
|
||||||
|
img = Img(cfn, self.image_path)
|
||||||
|
th = img.save()
|
||||||
|
if th:
|
||||||
|
sql = """INSERT INTO
|
||||||
|
thumbnails(file_id, filename)
|
||||||
|
VALUES(?, ?)"""
|
||||||
|
db_cursor.execute(sql, (fileid, th+"_t"))
|
||||||
|
sql = """INSERT INTO images(file_id, filename)
|
||||||
|
VALUES(?, ?)"""
|
||||||
|
db_cursor.execute(sql, (fileid, th))
|
||||||
|
os.unlink(cfn)
|
||||||
|
|
||||||
# Images - thumbnails and exif data
|
# Images - thumbnails and exif data
|
||||||
if self.config.confd['thumbs'] and ext in self.IMG:
|
if self.config.confd['thumbs'] and ext in self.IMG:
|
||||||
thumb = Thumbnail(current_file, self.image_path)
|
thumb = Thumbnail(current_file, self.image_path)
|
||||||
|
|||||||
@@ -1,53 +1,27 @@
|
|||||||
#!/usr/bin/env python
|
"""
|
||||||
# This Python file uses the following encoding: utf-8
|
Project: pyGTKtalog
|
||||||
#
|
Description: Test harvester and runner.
|
||||||
# Author: Roman 'gryf' Dobosz gryf@elysium.pl
|
Type: exec
|
||||||
#
|
Author: Roman 'gryf' Dobosz, gryf73@gmail.com
|
||||||
# Copyright (C) 2007 by Roman 'gryf' Dobosz
|
Created: 2008-12-15
|
||||||
#
|
"""
|
||||||
# This file is part of pyGTKtalog.
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation; either version 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software
|
|
||||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
# -------------------------------------------------------------------------
|
|
||||||
import sys
|
import sys
|
||||||
import unittest
|
import unittest
|
||||||
from os import path, chdir
|
from os import path, chdir
|
||||||
import glob
|
import glob
|
||||||
|
|
||||||
|
|
||||||
def my_import(module, name):
|
|
||||||
"""import replacement"""
|
|
||||||
mod = __import__(module, {}, {}, [name])
|
|
||||||
components = name.split('.')
|
|
||||||
for comp in components[1:]:
|
|
||||||
mod = getattr(mod, comp)
|
|
||||||
return mod
|
|
||||||
|
|
||||||
def setup_path():
|
def setup_path():
|
||||||
"""Sets up the python include paths to include needed directories"""
|
"""Sets up the python include paths to include needed directories"""
|
||||||
this_path = path.abspath(path.dirname(__file__))
|
this_path = path.abspath(path.dirname(__file__))
|
||||||
sys.path = [path.join(this_path, "../../src")] + sys.path
|
sys.path = [path.join(this_path, "../../src")] + sys.path
|
||||||
sys.path = [path.join(this_path, "../../src/test")] + sys.path
|
|
||||||
sys.path = [path.join(this_path, "../../src/test/unit")] + sys.path
|
sys.path = [path.join(this_path, "../../src/test/unit")] + sys.path
|
||||||
return
|
return
|
||||||
|
|
||||||
def build_suite():
|
def build_suite():
|
||||||
"""build suite test from files in unit directory"""
|
"""Build suite test from files in unit directory. Filenames with test
|
||||||
|
suites should always end with "_test.py"."""
|
||||||
modules = []
|
modules = []
|
||||||
classes = []
|
|
||||||
for fname in glob.glob1('unit', '*_test.py'):
|
for fname in glob.glob1('unit', '*_test.py'):
|
||||||
class_name = fname[:-8]
|
class_name = fname[:-8]
|
||||||
if "_" in class_name:
|
if "_" in class_name:
|
||||||
@@ -59,7 +33,6 @@ def build_suite():
|
|||||||
class_name = "Test" + class_name.capitalize()
|
class_name = "Test" + class_name.capitalize()
|
||||||
|
|
||||||
modules.append(fname[:-3])
|
modules.append(fname[:-3])
|
||||||
classes.append(class_name)
|
|
||||||
|
|
||||||
modules = map(__import__, modules)
|
modules = map(__import__, modules)
|
||||||
load = unittest.defaultTestLoader.loadTestsFromModule
|
load = unittest.defaultTestLoader.loadTestsFromModule
|
||||||
|
|||||||
@@ -1,9 +1,15 @@
|
|||||||
# This Python file uses the following encoding: utf-8
|
"""
|
||||||
|
Project: pyGTKtalog
|
||||||
|
Description: This is simple dummy test for... testing purposes :)
|
||||||
|
Type: test
|
||||||
|
Author: Roman 'gryf' Dobosz, gryf73@gmail.com
|
||||||
|
Created: 2008-12-15
|
||||||
|
"""
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
class TestDummy(unittest.TestCase):
|
class TestDummy(unittest.TestCase):
|
||||||
"""Fake test class"""
|
"""Fake test class"""
|
||||||
def test_dummyMethod(self):
|
def test_dummy_method(self):
|
||||||
"""Test simple assertion"""
|
"""Test simple assertion"""
|
||||||
self.assertTrue(True)
|
self.assertTrue(True)
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,15 @@
|
|||||||
# This Python file uses the following encoding: utf-8
|
"""
|
||||||
|
Project: pyGTKtalog
|
||||||
|
Description: This is another dummy test.
|
||||||
|
Type: test
|
||||||
|
Author: Roman 'gryf' Dobosz, gryf73@gmail.com
|
||||||
|
Created: 2008-12-15
|
||||||
|
"""
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
class TestFooBar(unittest.TestCase):
|
class TestFooBar(unittest.TestCase):
|
||||||
"""Fake test class"""
|
"""Fake test class"""
|
||||||
def test_dummyMethod(self):
|
def test_dummy_method(self):
|
||||||
"""Test simple assertion"""
|
"""Test simple assertion"""
|
||||||
self.assertTrue(True)
|
self.assertTrue(True)
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
# This Python file uses the following encoding: utf-8
|
"""
|
||||||
|
Project: pyGTKtalog
|
||||||
|
Description: Tests for Midentify class.
|
||||||
|
Type: test
|
||||||
|
Author: Roman 'gryf' Dobosz, gryf73@gmail.com
|
||||||
|
Created: 2008-12-15
|
||||||
|
"""
|
||||||
import unittest
|
import unittest
|
||||||
from lib.midentify import Midentify
|
from lib.midentify import Midentify
|
||||||
|
|
||||||
@@ -8,82 +14,82 @@ class TestMidentify(unittest.TestCase):
|
|||||||
Midentify script belongs to mplayer package.
|
Midentify script belongs to mplayer package.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def test_testAvi(self):
|
def test_avi(self):
|
||||||
"""test mock avi file, should return dict with expected values"""
|
"""test mock avi file, should return dict with expected values"""
|
||||||
avi = Midentify("mocks/m.avi")
|
avi = Midentify("mocks/m.avi")
|
||||||
result_dict = avi.get_data()
|
result_dict = avi.get_data()
|
||||||
self.assertTrue(len(result_dict) != 0, "result should have lenght > 0")
|
self.assertTrue(len(result_dict) != 0, "result should have lenght > 0")
|
||||||
self.assertEqual(result_dict['audio_format'], '85')
|
self.assertEqual(result_dict['audio_format'], '85')
|
||||||
self.assertEqual(result_dict['width'], '128')
|
self.assertEqual(result_dict['width'], 128)
|
||||||
self.assertEqual(result_dict['audio_no_channels'], '2')
|
self.assertEqual(result_dict['audio_no_channels'], 2)
|
||||||
self.assertEqual(result_dict['height'], '96')
|
self.assertEqual(result_dict['height'], 96)
|
||||||
self.assertEqual(result_dict['video_format'], 'XVID')
|
self.assertEqual(result_dict['video_format'], 'XVID')
|
||||||
self.assertEqual(result_dict['length'], '4')
|
self.assertEqual(result_dict['length'], 4)
|
||||||
self.assertEqual(result_dict['audio_codec'], 'mp3')
|
self.assertEqual(result_dict['audio_codec'], 'mp3')
|
||||||
self.assertEqual(result_dict['video_codec'], 'ffodivx')
|
self.assertEqual(result_dict['video_codec'], 'ffodivx')
|
||||||
self.assertEqual(result_dict['duration'], '00:00:04')
|
self.assertEqual(result_dict['duration'], '00:00:04')
|
||||||
self.assertEqual(result_dict['container'], 'avi')
|
self.assertEqual(result_dict['container'], 'avi')
|
||||||
|
|
||||||
def test_testAvi2(self):
|
def test_avi2(self):
|
||||||
"""test another mock avi file, should return dict with expected
|
"""test another mock avi file, should return dict with expected
|
||||||
values"""
|
values"""
|
||||||
avi = Midentify("mocks/m1.avi")
|
avi = Midentify("mocks/m1.avi")
|
||||||
result_dict = avi.get_data()
|
result_dict = avi.get_data()
|
||||||
self.assertTrue(len(result_dict) != 0, "result should have lenght > 0")
|
self.assertTrue(len(result_dict) != 0, "result should have lenght > 0")
|
||||||
self.assertEqual(result_dict['audio_format'], '85')
|
self.assertEqual(result_dict['audio_format'], '85')
|
||||||
self.assertEqual(result_dict['width'], '128')
|
self.assertEqual(result_dict['width'], 128)
|
||||||
self.assertEqual(result_dict['audio_no_channels'], '2')
|
self.assertEqual(result_dict['audio_no_channels'], 2)
|
||||||
self.assertEqual(result_dict['height'], '96')
|
self.assertEqual(result_dict['height'], 96)
|
||||||
self.assertEqual(result_dict['video_format'], 'H264')
|
self.assertEqual(result_dict['video_format'], 'H264')
|
||||||
self.assertEqual(result_dict['length'], '4')
|
self.assertEqual(result_dict['length'], 4)
|
||||||
self.assertEqual(result_dict['audio_codec'], 'mp3')
|
self.assertEqual(result_dict['audio_codec'], 'mp3')
|
||||||
self.assertEqual(result_dict['video_codec'], 'ffh264')
|
self.assertEqual(result_dict['video_codec'], 'ffh264')
|
||||||
self.assertEqual(result_dict['duration'], '00:00:04')
|
self.assertEqual(result_dict['duration'], '00:00:04')
|
||||||
self.assertEqual(result_dict['container'], 'avi')
|
self.assertEqual(result_dict['container'], 'avi')
|
||||||
|
|
||||||
def test_testMkv(self):
|
def test_mkv(self):
|
||||||
"""test mock mkv file, should return dict with expected values"""
|
"""test mock mkv file, should return dict with expected values"""
|
||||||
avi = Midentify("mocks/m.mkv")
|
avi = Midentify("mocks/m.mkv")
|
||||||
result_dict = avi.get_data()
|
result_dict = avi.get_data()
|
||||||
self.assertTrue(len(result_dict) != 0, "result should have lenght > 0")
|
self.assertTrue(len(result_dict) != 0, "result should have lenght > 0")
|
||||||
self.assertEqual(result_dict['audio_format'], '8192')
|
self.assertEqual(result_dict['audio_format'], '8192')
|
||||||
self.assertEqual(result_dict['width'], '128')
|
self.assertEqual(result_dict['width'], 128)
|
||||||
self.assertEqual(result_dict['audio_no_channels'], '2')
|
self.assertEqual(result_dict['audio_no_channels'], 2)
|
||||||
self.assertEqual(result_dict['height'], '96')
|
self.assertEqual(result_dict['height'], 96)
|
||||||
self.assertEqual(result_dict['video_format'], 'mp4v')
|
self.assertEqual(result_dict['video_format'], 'mp4v')
|
||||||
self.assertEqual(result_dict['length'], '4')
|
self.assertEqual(result_dict['length'], 4)
|
||||||
self.assertEqual(result_dict['audio_codec'], 'a52')
|
self.assertEqual(result_dict['audio_codec'], 'a52')
|
||||||
self.assertEqual(result_dict['video_codec'], 'ffodivx')
|
self.assertEqual(result_dict['video_codec'], 'ffodivx')
|
||||||
self.assertEqual(result_dict['duration'], '00:00:04')
|
self.assertEqual(result_dict['duration'], '00:00:04')
|
||||||
self.assertEqual(result_dict['container'], 'mkv')
|
self.assertEqual(result_dict['container'], 'mkv')
|
||||||
|
|
||||||
def test_testMpg(self):
|
def test_mpg(self):
|
||||||
"""test mock mpg file, should return dict with expected values"""
|
"""test mock mpg file, should return dict with expected values"""
|
||||||
avi = Midentify("mocks/m.mpg")
|
avi = Midentify("mocks/m.mpg")
|
||||||
result_dict = avi.get_data()
|
result_dict = avi.get_data()
|
||||||
self.assertTrue(len(result_dict) != 0, "result should have lenght > 0")
|
self.assertTrue(len(result_dict) != 0, "result should have lenght > 0")
|
||||||
self.assertFalse(result_dict.has_key('audio_format'))
|
self.assertFalse(result_dict.has_key('audio_format'))
|
||||||
self.assertEqual(result_dict['width'], '128')
|
self.assertEqual(result_dict['width'], 128)
|
||||||
self.assertFalse(result_dict.has_key('audio_no_channels'))
|
self.assertFalse(result_dict.has_key('audio_no_channels'))
|
||||||
self.assertEqual(result_dict['height'], '96')
|
self.assertEqual(result_dict['height'], 96)
|
||||||
self.assertEqual(result_dict['video_format'], '0x10000001')
|
self.assertEqual(result_dict['video_format'], '0x10000001')
|
||||||
self.assertFalse(result_dict.has_key('lenght'))
|
self.assertFalse(result_dict.has_key('lenght'))
|
||||||
self.assertFalse(result_dict.has_key('audio_codec'))
|
self.assertFalse(result_dict.has_key('audio_codec'))
|
||||||
self.assertEqual(result_dict['video_codec'], 'mpegpes')
|
self.assertEqual(result_dict['video_codec'], 'ffmpeg1')
|
||||||
self.assertFalse(result_dict.has_key('duration'))
|
self.assertFalse(result_dict.has_key('duration'))
|
||||||
self.assertEqual(result_dict['container'], 'mpeges')
|
self.assertEqual(result_dict['container'], 'mpeges')
|
||||||
|
|
||||||
def test_testOgm(self):
|
def test_ogm(self):
|
||||||
"""test mock ogm file, should return dict with expected values"""
|
"""test mock ogm file, should return dict with expected values"""
|
||||||
avi = Midentify("mocks/m.ogm")
|
avi = Midentify("mocks/m.ogm")
|
||||||
result_dict = avi.get_data()
|
result_dict = avi.get_data()
|
||||||
self.assertTrue(len(result_dict) != 0, "result should have lenght > 0")
|
self.assertTrue(len(result_dict) != 0, "result should have lenght > 0")
|
||||||
self.assertEqual(result_dict['audio_format'], '8192')
|
self.assertEqual(result_dict['audio_format'], '8192')
|
||||||
self.assertEqual(result_dict['width'], '160')
|
self.assertEqual(result_dict['width'], 160)
|
||||||
self.assertEqual(result_dict['audio_no_channels'], '2')
|
self.assertEqual(result_dict['audio_no_channels'], 2)
|
||||||
self.assertEqual(result_dict['height'], '120')
|
self.assertEqual(result_dict['height'], 120)
|
||||||
self.assertEqual(result_dict['video_format'], 'H264')
|
self.assertEqual(result_dict['video_format'], 'H264')
|
||||||
self.assertEqual(result_dict['length'], '4')
|
self.assertEqual(result_dict['length'], 4)
|
||||||
self.assertEqual(result_dict['audio_codec'], 'a52')
|
self.assertEqual(result_dict['audio_codec'], 'a52')
|
||||||
self.assertEqual(result_dict['video_codec'], 'ffh264')
|
self.assertEqual(result_dict['video_codec'], 'ffh264')
|
||||||
self.assertEqual(result_dict['duration'], '00:00:04')
|
self.assertEqual(result_dict['duration'], '00:00:04')
|
||||||
|
|||||||
Reference in New Issue
Block a user