예제 #1
0
        /**
         * Lo scopo di questa operazione è quella di scaricare le foto
         * dalla flash card all'hard disk locale il più velocemente
         * possibile. In questo modo posso congedare il fotografo che
         * sta aspettando. Durante questa fase, non ho feedback con l'utente.
         * Terminato lo scarico, allora posso muovere il file nella giusta
         * cartella di destinazione, scrivendo nel database e sollevando gli
         * eventi per poter visualizzare le foto.
         */
        public void scarica(ParamScarica paramScarica)
        {
            _paramScarica = paramScarica;

            seNonPossoScaricareSpaccati();

            // Se per sbaglio ho ancora un worker aperto, lo chiudo
            chiudiWorker();

            // --- Pubblico un messaggio di inizio scaricamento foto
            ScaricoFotoMsg scaricoFotoMsg = new ScaricoFotoMsg(this, "Inizio Scarico Foto");

            scaricoFotoMsg.esitoScarico = new EsitoScarico {
                riscontratiErrori = false
            };
            scaricoFotoMsg.fase            = FaseScaricoFoto.InizioScarico;
            scaricoFotoMsg.sorgente        = _paramScarica.cartellaSorgente != null ? _paramScarica.cartellaSorgente : _paramScarica.nomeFileSingolo;
            scaricoFotoMsg.showInStatusBar = true;
            pubblicaMessaggio(scaricoFotoMsg);
            // ---

            // Creo il worker che copierà le foto in background
            _copiaImmaginiWorker = new CopiaImmaginiWorker(paramScarica, elaboraFotoAcquisite);

            // Lancio il worker che scarica ed elabora le foto.
            bool usaThreadSeparato = String.IsNullOrEmpty(paramScarica.nomeFileSingolo);

            if (usaThreadSeparato)
            {
                _copiaImmaginiWorker.Start();
            }
            else
            {
                _copiaImmaginiWorker.StartSingleThread();
            }

            statoScarica = StatoScarica.Scaricamento;
        }
        /// <summary>
        /// Il parametro passato "tempoScarico" deve essere ribaltato su tutte le foto, perché
        /// serve a creare una relazione implicita 1-n tra lo ScaricoCard e Fotografia
        /// </summary>
        /// <param name="tempoScarico"></param>
        public void elabora(DateTime tempoScarico)
        {
            _giornale.Debug("Inizio ad elaborare le foto acquisite");

            // carico il fotografo che rimane uguale per tutta questa sessione di elaborazione
            LumenEntities objContext = UnitOfWorkScope.currentDbContext;

            _fotografo = objContext.Fotografi.Single <Fotografo>(ff => ff.id == _paramScarica.flashCardConfig.idFotografo);


            // carico l'evento che rimane uguale per tutta questa sessione di elaborazione
            if (_paramScarica.flashCardConfig.idEvento != null && _paramScarica.flashCardConfig.idEvento != Guid.Empty)
            {
                _evento = objContext.Eventi.SingleOrDefault(e => e.id == _paramScarica.flashCardConfig.idEvento);
            }


            _giornale.Debug("Sto per lavorare le " + _listaFiles.Count + " foto appena acquisite di " + _fotografo.id);

            int ultimoNumFoto = NumeratoreFotogrammi.incrementaNumeratoreFoto(_listaFiles.Count);

            contaAggiunteDb = 0;

            ScaricoFotoMsg scaricoFotoMsg = new ScaricoFotoMsg(this, "Notifica progresso");

            scaricoFotoMsg.fase         = FaseScaricoFoto.Provinatura;
            scaricoFotoMsg.esitoScarico = new EsitoScarico();
            scaricoFotoMsg.esitoScarico.totFotoScaricate = _listaFiles.Count;
            scaricoFotoMsg.sorgente        = _paramScarica.cartellaSorgente != null ? _paramScarica.cartellaSorgente : _paramScarica.nomeFileSingolo;
            scaricoFotoMsg.showInStatusBar = false;

            IList <Fotografia> fotoDaEsaminare = null;

            if (_paramScarica.ricercaBarCode)
            {
                fotoDaEsaminare = new List <Fotografia>();
            }

            foreach (FileInfo fileInfo in _listaFiles)
            {
                // Eseguo una transazione per ogni foto, in questo modo sono sicuro che tutto quello che posso buttare dentro, ci va.
                using (TransactionScope transaction = new TransactionScope()) {
                    try {
                        int proxNum = 1 + contaAggiunteDb + ultimoNumFoto;

                        Fotografia foto = aggiungiFoto(fileInfo, proxNum, tempoScarico);

                        //
                        // --- eventuale maschera automatica
                        if (_paramScarica.mascheraAuto != null)
                        {
                            // Uso la maschera nella sua dimensione naturale
                            Imaging.Correzioni.Mascheratura mascheraratura = new Imaging.Correzioni.Mascheratura {
                                nome   = _paramScarica.mascheraAuto.nomeFile,
                                width  = _paramScarica.mascheraAuto.imgOriginale.ww,
                                height = _paramScarica.mascheraAuto.imgOriginale.hh
                            };

                            fotoRitoccoSrv.addCorrezione(foto, mascheraratura, false);
                        }

                        // Mark the transaction as complete.
                        transaction.Complete();


                        // Incremento qui il contatore perché in caso di eccezione, voglio che non si incrementi
                        ++contaAggiunteDb;


                        _giornale.Debug("Inizio Provinatura immagine " + fileInfo.FullName);
                        AiutanteFoto.creaProvinoFoto(fileInfo.FullName, foto);
                        _giornale.Debug("Fine Provinatura immagine ");

                        // Libero la memoria occupata dalle immagini, altrimenti esplode.
                        AiutanteFoto.disposeImmagini(foto, IdrataTarget.Tutte);

                        if (_paramScarica.ricercaBarCode)
                        {
                            fotoDaEsaminare.Add(foto);
                        }

                        // Se lavoro con una singola foto, allora lancio l'evento che mi dice che è pronta.
                        if (String.IsNullOrEmpty(_paramScarica.nomeFileSingolo) == false)
                        {
                            // Quando sono a posto con la foto, sollevo un evento per avvisare tutti
                            // Siccome questa operazione è un pò onerosa, per il momento la abilito
                            // soltanto sulla singola foto. Se ne scarico 1000 di foto, non voglio lanciare 1000 eventi!!!
                            NuovaFotoMsg msg = new NuovaFotoMsg(this, foto);
                            LumenApplication.Instance.bus.Publish(msg);
                        }
                        _giornale.Debug("ok nuova foto provinata e inserita nel db: " + foto);

                        if (contaAggiunteDb % 20 == 0)
                        {
                            scaricoFotoMsg.esitoScarico.totFotoProvinateProg = contaAggiunteDb;
                            LumenApplication.Instance.bus.Publish(scaricoFotoMsg);
                        }
                    } catch (Exception ee) {
                        transaction.Dispose();
                        _giornale.Error("Errore elaborazione foto. Viene ignorata " + fileInfo, ee);
                    }
                }
            }

            if (_paramScarica.ricercaBarCode)
            {
                barCodeSrv.scan(fotoDaEsaminare);
            }

            if (contaAggiunteDb != 0)
            {
                scaricoFotoMsg.esitoScarico.totFotoProvinateProg = contaAggiunteDb;
                scaricoFotoMsg.esitoScarico.totFotoProvinate     = contaAggiunteDb;
                LumenApplication.Instance.bus.Publish(scaricoFotoMsg);
            }

            _giornale.Info("Terminato di lavorare " + _listaFiles.Count + " foto appena acquisite");

            incrementaTotaleFotoScaricate(tempoScarico);
        }
예제 #3
0
        private void elaboraFotoAcquisite(EsitoScarico esitoScarico)
        {
            _giornale.Debug("Inizio elaboraFotoAcquisite()");

            StringBuilder msg = new StringBuilder();

            if (esitoScarico.riscontratiErrori)
            {
                msg.AppendFormat("Errore in acquisizione {0} foto. Verificare!", esitoScarico.totFotoCopiateOk);
            }
            else
            {
                msg.AppendFormat("Scaricate OK {0} foto.", +esitoScarico.totFotoCopiateOk);
            }
            msg.Append(" Togliere la card");

            ScaricoFotoMsg scaricoFotoMsg = new ScaricoFotoMsg(this, msg.ToString());

            scaricoFotoMsg.esitoScarico = esitoScarico;
            scaricoFotoMsg.esito        = esitoScarico.riscontratiErrori ? Esito.Errore : Esito.Ok;
            // Finito: genero un evento per notificare che l'utente può togliere la flash card.
            scaricoFotoMsg.fase            = FaseScaricoFoto.FineScarico;
            scaricoFotoMsg.sorgente        = _paramScarica.cartellaSorgente != null ? _paramScarica.cartellaSorgente : _paramScarica.nomeFileSingolo;
            scaricoFotoMsg.showInStatusBar = true;

            // battezzo la flashcard al fotografo corrente
            battezzaFlashCard(_paramScarica);

            // Se il drive che ho appena scaricato è rimovibile, allora lo smonto
            // Richiesta di Ciccio del 29-03-2018 non smontiamo piu la card
            // smontaSeRimovibile();



            // Rendo pubblico l'esito dello scarico in modo che la UI possa notificare l'utente di togliere
            // la flash card.

            /*
             * per l'onride mi serve che lanci il msg anche su un solo file
             * però mi pare che nessuno utilizzi il modo singolo. quindi lo pubblico sempre
             *
             * if( _paramScarica.nomeFileSingolo == null && _paramScarica.cartellaSorgente != null )
             */
            pubblicaMessaggio(scaricoFotoMsg);

            _giornale.Debug("Scaricate " + esitoScarico.totFotoCopiateOk + " foto. Si può togliere la card");

            // -- inizio elaborazione

            ElaboratoreFotoAcquisite elab = new ElaboratoreFotoAcquisite(esitoScarico.fotoDaLavorare, _paramScarica);

            statoScarica = StatoScarica.Provinatura;
            elab.elabora(esitoScarico.tempo);

            _giornale.Debug("Elaborazione terminata. Inserite " + elab.contaAggiunteDb + " foto nel database");

            statoScarica = StatoScarica.Idle;

            // Rendo pubblico l'esito dell'elaborazione così che si può aggiornare la libreria.
            scaricoFotoMsg.esitoScarico.totFotoProvinate = elab.contaAggiunteDb;
            if (scaricoFotoMsg.esitoScarico.totFotoProvinate != scaricoFotoMsg.esitoScarico.totFotoScaricate)
            {
                scaricoFotoMsg.esitoScarico.riscontratiErrori = true;
            }

            scaricoFotoMsg.fase            = FaseScaricoFoto.FineLavora;
            scaricoFotoMsg.descrizione     = "Provinatura foto terminata. Inserite " + elab.contaAggiunteDb + " foto nel database";
            scaricoFotoMsg.showInStatusBar = true;
            pubblicaMessaggio(scaricoFotoMsg);

            // Chiudo il worker che ha finito il suo lavoro
            // _copiaImmaginiWorker.Stop();


            // Faccio un controllo: Se le foto scaricate non coincidono con quelle elaborate (ovvero scritte nel db e provinate)
            // Allora c'è stato un problema. Devo avvisare l'utente di ricostruire il database
            bool problemiInVista = (esitoScarico.riscontratiErrori || esitoScarico.totFotoCopiateOk != elab.contaAggiunteDb);

            if (problemiInVista)
            {
                // TODO stampare nel log tutto l'oggetto EsitoScarico
                _giornale.Warn(String.Format("Riscontrata incongruenza database. copiate={0} elab={1}", esitoScarico.totFotoCopiateOk, elab.contaAggiunteDb));

                RilevataInconsistenzaDatabaseMsg inconsistenzaMsg = new RilevataInconsistenzaDatabaseMsg(this);
                inconsistenzaMsg.descrizione          = "Inconsistenza database. Lanciare ricostruzione!";
                inconsistenzaMsg.showInStatusBar      = true;
                inconsistenzaMsg.giornataDaVerificare = LumenApplication.Instance.stato.giornataLavorativa;
                pubblicaMessaggio(inconsistenzaMsg);
            }
        }
예제 #4
0
        /**
         * Processo reale di trasferimento immagini
         */
        protected override void Work()
        {
            int conta = 0;



            _giornale.Debug("Inizio a trasferire le foto da " + _paramScarica.cartellaSorgente);



            string nomeDirDest = calcolaCartellaDestinazione();

            // Creo la cartella che conterrà le foto
            Directory.CreateDirectory(nomeDirDest);

            // Creo la cartella che conterrà i provini
            PathUtil.creaCartellaProvini(new FileInfo(nomeDirDest));

            _esitoScarico = new EsitoScarico();

            ScaricoFotoMsg scaricoFotoMsg = new ScaricoFotoMsg(this, "Notifica progresso");

            scaricoFotoMsg.fase            = FaseScaricoFoto.Scaricamento;
            scaricoFotoMsg.esitoScarico    = _esitoScarico;
            scaricoFotoMsg.sorgente        = _paramScarica.cartellaSorgente != null ? _paramScarica.cartellaSorgente : _paramScarica.nomeFileSingolo;
            scaricoFotoMsg.showInStatusBar = false;

            try {
                if (_paramScarica.nomeFileSingolo != null)
                {
                    // Lavoro un solo file che mi è stato indicato. Serve per creare una maschera quando lavoro con le cornici.
                    if (scaricaAsincronoUnFile(_paramScarica.nomeFileSingolo, nomeDirDest))
                    {
                        ++conta;
                        if (conta % 20 == 0)
                        {
                            scaricoFotoMsg.esitoScarico.totFotoScaricateProg = conta;
                            LumenApplication.Instance.bus.Publish(scaricoFotoMsg);
                        }
                    }
                    else
                    {
                        // La copia di questo file non è andata a buon fine
                        _esitoScarico.riscontratiErrori = true;
                    }
                }
                else
                {
                    // Faccio giri diversi per i vari formati grafici che sono indicati nella configurazione (jpg, tif)
                    string[] estensioni = Configurazione.UserConfigLumen.estensioniGrafiche.Split(';');
                    foreach (string estensione in estensioni)
                    {
                        string[] files = Directory.GetFiles(_paramScarica.cartellaSorgente, searchPattern: "*" + estensione, searchOption: SearchOption.AllDirectories);

                        // trasferisco tutti i files elencati
                        foreach (string nomeFileSrc in files)
                        {
                            if (scaricaAsincronoUnFile(nomeFileSrc, nomeDirDest))
                            {
                                ++conta;
                                if (conta % 20 == 0)
                                {
                                    scaricoFotoMsg.esitoScarico.totFotoScaricateProg = conta;
                                    LumenApplication.Instance.bus.Publish(scaricoFotoMsg);
                                }
                            }
                            else
                            {
                                // La copia di questo file non è andata a buon fine
                                _esitoScarico.riscontratiErrori = true;
                            }
                        }
                    }
                }
            } catch (Exception qq) {
                // Se casco qui, probabilmente è perché è stata sfilata la memorycard prima che sia completato lo scarico.
                _esitoScarico.riscontratiErrori = true;
                _giornale.Error("Errore imprevisto durante scarico card", qq);
            }

            if (conta != 0)
            {
                scaricoFotoMsg.esitoScarico.totFotoScaricate     = conta;
                scaricoFotoMsg.esitoScarico.totFotoScaricateProg = conta;
                LumenApplication.Instance.bus.Publish(scaricoFotoMsg);
            }

            // Nel log scrivo anche il tempo che ci ho messo a scaricare le foto. Mi servirà per profilare
            TimeSpan tempoImpiegato = DateTime.Now.Subtract(_esitoScarico.tempo);

            _giornale.Info("Terminato trasferimento di " + conta + " foto. Tempo impiegato = " + tempoImpiegato);


            // Deve essere già aperto
            using (new UnitOfWorkScope(true)) {
                // ::: Ultima fase eleboro le foto memorizzando nel db e creando le dovute cache
                _elaboraImmaginiAcquisiteCallback.Invoke(_esitoScarico);
            }

            _giornale.Debug("Terminato background worker per copia files");
        }