#!/usr/bin/python
# -*- coding: utf-8 -*-

###########################################################################
# Imports/exports user accounds from/to various sources.
#
# Copyright (C) 2009 Τεχνική Στήριξη ΣΕΠΕΗΥ <devs@ts.sch.gr>
#  * Original:
#    Sep 2009 - Alkis Georgopoulos <alkisg@gmail.com>
#    Sep 2009 - Fotis Tsamis <ftsamis@gmail.com>
#
# 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 3 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, see <http://www.gnu.org/licenses/>.
#
# On Debian GNU/Linux systems, the complete text of the GNU General
# Public License can be found in `/usr/share/common-licenses/GPL".
###########################################################################

import pygtk
pygtk.require('2.0')
import gtk
import gtk.glade
import sys
sys.path.append('/usr/share/sch-scripts/scripts/common')
from schscripts.lib_users import *


class Main:
    def InfoDialog(self, text, title="Πληροφορία"):
        dialog = gtk.MessageDialog(None, 0, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, text)
        dialog.set_title(title)
        image = dialog.render_icon(gtk.STOCK_DIALOG_INFO, gtk.ICON_SIZE_DIALOG)
        dialog.set_icon(image)
        dialog.run()
        dialog.destroy()

    def ErrorDialog(self, text, title="Σφάλμα"):
        dialog = gtk.MessageDialog(None, 0, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, text)
        dialog.set_title(title)
        image = dialog.render_icon(gtk.STOCK_DIALOG_ERROR, gtk.ICON_SIZE_DIALOG)
        dialog.set_icon(image)
        dialog.run()
        dialog.destroy()

    def __init__(self):
        #Set the Glade file
        self.gladefile = "/usr/share/sch-scripts/scripts/users/import-export-users.glade"
        self.wTree = gtk.Builder()
        self.wTree.add_from_file(self.gladefile)
        dic = {"on_mainwindow_destroy" : self.kill,
              "on_read_passwd" : self.ReadPasswd,
              "on_import_sch" : self.ImportSch,
              "on_import_csv" : self.ImportCsv,
              "on_export_csv" : self.ExportCsv,
              "on_write_passwd" : self.WritePasswd,
              "on_help_contents" : self.HelpContents,
              "on_help_about" : self.HelpAbout}
        self.wTree.connect_signals(dic)
        
        self.tree = self.wTree.get_object("treeview")        
        
        counter = 0
        for header in FIELD_NAMES:
            self.AddColumn(header, counter)
            counter = counter + 1        
        
        self.usersList = gtk.ListStore(str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str)
        self.tree.set_model(self.usersList)
        
        self.clipboard = gtk.clipboard_get(gtk.gdk.SELECTION_CLIPBOARD)

        # Show the users of the system when program starts
        self.ReadPasswd(self)
            
        
    def AddColumn(self, title, columnId):
        """This function adds a column to the list view.
        First it creates the gtk.TreeViewColumn and then set
        some needed properties"""
                        
        column = gtk.TreeViewColumn(title, gtk.CellRendererText()
            , text=columnId)
        column.set_resizable(True)        
        column.set_sort_column_id(columnId)
        self.tree.append_column(column)


    def LoadUsers(self, new_users):
        """Puts the users in the gtkTreeView"""
        self.users = new_users
        self.usersList.clear()
        for name, u in self.users.iteritems():
            data = [u.name, u.uid, u.rname, u.office, u.wphone, u.hphone, u.dir, u.shell, ",".join(u.groups), u.min, u.max, u.warn, u.inact, u.expire, u.pwd, u.plainpw]
            self.usersList.append(data)


    def ReadPasswd(self, widget):
        """Loads the users list from the system."""
        self.LoadUsers(read_users_from_passwd())
    
    
    def ImportSch(self, widget):
        """Loads the users list from a csv file."""
        dialog = self.wTree.get_object("dlgImportSch")
        result = dialog.run()
        dialog.hide()
        if result != 2:  # TODO: maybe use a constant?
            return
        clipboard_data = self.clipboard.wait_for_text()
        new_users = import_users_from_sch(clipboard_data)
        if new_users == {}:
            self.ErrorDialog("Το πρόχειρο δεν είχε την κατάλληλη μορφή που χρειάζεται για να γίνει επικόλληση χρηστών από το ΠΣΔ.")
            return
        self.LoadUsers(new_users)
    
    
    def ImportCsv(self, widget):
        """Loads the users list from a csv file."""
        csvfile = self.FileChooser('open')
        if csvfile is None:
            return
        new_users = import_users_from_csv(csvfile)
        if new_users == {}:
            self.ErrorDialog("Εσφαλμένες επικεφαλίδες στο αρχείο " + csvfile + ".\nΧρησιμοποιήστε ως πρότυπο το .csv αρχείο που παράγεται από το μενού Χρήστες » Εξαγωγή ως csv, και μην πειράξετε τις επικεφαλίδες.")
            return
        self.LoadUsers(new_users)
    
    
    def ExportCsv(self, widget):
        """Saves the current users list in a file (csv format)."""
        FileToExport = self.FileChooser('save')
        if FileToExport is not None:
            export_users_to_csv(self.users, FileToExport)


    def WritePasswd(self, widget):
        """Loads the users list from the system."""
        write_users_to_passwd(self.users)
        self.InfoDialog("Έγινε προσθήκη των χρηστών στο σύστημα. Πατήστε το μενού «Ανάγνωση των χρηστών του συστήματος» εάν θέλετε να γίνει ενημέρωση του παραθύρου.")
    
    
    def HelpContents(self, widget):
        """Shows the help contents."""
        self.InfoDialog("""Μερικά σημεία που χρίζουν προσοχής:

 * Για να κάνετε εισαγωγή από .csv, πηγαίνετε πρώτα στο μενού «Εξαγωγή χρηστών σε αρχείο .csv» και χρησιμοποιήστε εκείνο το αρχείο ως πρότυπο, χωρίς να πειράξετε τις επικεφαλίδες του.

 * Όταν κάνετε εισαγωγή χρηστών, στο διάλογο προβάλλονται μόνο οι καινούργιοι χρήστες που θέλετε να εισαχθούν, όχι οι χρήστες του συστήματος. Θα πρέπει να επιλέξετε το «Προσθήκη των χρηστών στο σύστημα» για να αποθηκευτούν.
        """)


    def HelpAbout(self, widget):
        """Shows the about dialog."""
        dialog = self.wTree.get_object("dlgAbout")
        result = dialog.run()
        dialog.hide()

    
    def kill(self, widget):
        exit(0)
    
    
    def FileChooser(self, mode):
        if mode == 'save':
            dialog = gtk.FileChooserDialog("Εξαγωγή csv",
                                          None,
                                          gtk.FILE_CHOOSER_ACTION_SAVE,
                                          (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
                                           gtk.STOCK_SAVE, gtk.RESPONSE_OK))
        else:
            dialog = gtk.FileChooserDialog("Εισαγωγή από csv",
                                          None,
                                          gtk.FILE_CHOOSER_ACTION_OPEN,
                                          (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
                                           gtk.STOCK_OPEN, gtk.RESPONSE_OK))
        gtk.FileChooser.set_do_overwrite_confirmation(dialog, True)
        dialog.set_default_response(gtk.RESPONSE_OK)

        filter = gtk.FileFilter()
        filter.set_name("Αρχεία .csv")
        filter.add_pattern("*.csv")
        dialog.add_filter(filter)

        filter = gtk.FileFilter()
        filter.set_name("Όλα τα αρχεία")
        filter.add_pattern("*")
        dialog.add_filter(filter)

        response = dialog.run()
        if response == gtk.RESPONSE_OK:
            outfile = dialog.get_filename()
        else:
            outfile = None
        dialog.destroy()

        return outfile            
    


if __name__ == '__main__':
    Main()
    gtk.main()
