~facundo/encuentro/trunk

« back to all changes in this revision

Viewing changes to encuentro/main.py

  • Committer: Facundo Batista
  • Date: 2011-11-06 15:03:50 UTC
  • Revision ID: facundo@taniquetil.com.ar-20111106150350-65wkfffco13h7n8h
Now you can filter by the title.

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
 
21
21
 
22
22
import bz2
 
23
import json
23
24
import logging
24
25
import os
25
26
import pickle
26
27
import subprocess
27
 
import json
28
28
import user
29
29
 
 
30
from unicodedata import normalize
 
31
 
30
32
from encuentro import import_exit
31
33
 
32
34
# gtk import and magic to work with twisted
87
89
    }
88
90
 
89
91
    def __init__(self, titulo, seccion, sinopsis, tematica, duracion, nroemis,
90
 
                 state=None, progress=None, filename=None):
 
92
                 state=None, progress=None, filename=None, to_filter=''):
91
93
        self.titulo = titulo
92
94
        self.seccion = seccion
93
95
        self.sinopsis = sinopsis
97
99
        self.progress = progress
98
100
        self.filename = filename
99
101
        self.nroemis = nroemis
 
102
        self.to_filter = to_filter
100
103
 
101
104
    def __str__(self):
102
105
        return "<EpisodeData [%d] (%s) %r>" % (self.nroemis,
103
106
                                               self.state, self.titulo)
104
107
 
105
 
    def get_row_data(self):
 
108
    def get_row_data(self, mark=None):
106
109
        """Return the data for the liststore row."""
107
 
        data = (self.titulo, self.seccion, self.tematica,
 
110
        if mark is None:
 
111
            title = self.titulo
 
112
        else:
 
113
            pos1, length = mark
 
114
            pos2 = pos1 + length
 
115
            t = self.titulo
 
116
            title = ''.join(t[:pos1] + '<span background="yellow">' +
 
117
                            t[pos1:pos2] + '</span>' + t[pos2:])
 
118
        data = (title, self.seccion, self.tematica,
108
119
                self.duracion, self.nroemis, self._get_nice_state())
109
120
        return data
110
121
 
280
291
            self.programs_data = {}
281
292
        logger.info("Episodes metadata loaded (%d)", len(self.programs_data))
282
293
 
 
294
        # check if we need to update "to_filter"
 
295
        one_program = self.programs_data.values()[:1]
 
296
        if one_program:
 
297
            if getattr(one_program[0], 'to_filter', None) is None:
 
298
                for p in self.programs_data.itervalues():
 
299
                    p.to_filter = self._prepare_to_filter(p.titulo)
 
300
 
283
301
        # get config from file, or defaults
284
302
        if os.path.exists(self._config_file):
285
303
            with open(self._config_file) as fh:
335
353
        """Return if metadata is needed."""
336
354
        return bool(self.programs_data)
337
355
 
 
356
    def _prepare_to_filter(self, text):
 
357
        """Prepare a text to filter.
 
358
 
 
359
        It receives unicode, but return simple lowercase ascii.
 
360
        """
 
361
        return normalize('NFKD', text).encode('ASCII', 'ignore').lower()
 
362
 
338
363
    def review_need_something_indicator(self):
339
364
        """Start the wizard if needed, or hide the need config button."""
340
365
        if not self._have_config() or not self._have_metadata():
396
421
            except KeyError:
397
422
                ed = EpisodeData(titulo=titulo, seccion=seccion,
398
423
                                 sinopsis=sinopsis, tematica=tematica,
399
 
                                 duracion=duracion, nroemis=nroemis)
 
424
                                 duracion=duracion, nroemis=nroemis,
 
425
                                 to_filter=self._prepare_to_filter(titulo))
400
426
                self.programs_data[nroemis] = ed
401
427
            else:
402
428
                epis.titulo = titulo
409
435
        self.refresh_treeview()
410
436
        self._save_states()
411
437
 
412
 
    def refresh_treeview(self):
 
438
    def refresh_treeview(self, field_filter=''):
413
439
        """Update the liststore of the programs."""
414
440
        columns = [self.programs_store.get_column_type(i)
415
441
                   for i in range(self.programs_store.get_n_columns())]
416
442
        new_liststore = gtk.ListStore(*columns)
 
443
        len_filter = len(field_filter)
417
444
        for p in self.programs_data.itervalues():
418
 
            new_liststore.append(p.get_row_data())
 
445
            if field_filter:
 
446
                # it's being filtered
 
447
                pos = p.to_filter.find(field_filter)
 
448
                if pos == -1:
 
449
                    continue
 
450
                new_liststore.append(p.get_row_data((pos, len_filter)))
 
451
            else:
 
452
                new_liststore.append(p.get_row_data())
419
453
        self.programs_treeview.set_model(new_liststore)
420
454
 
421
455
        # pograms_store was defined before, yes! pylint: disable=W0201
423
457
        # FIXME(3): que luego de actualizar reordene
424
458
        # FIXME(3): que duracion y episodio esten justified a la derecha
425
459
 
 
460
    def on_filter_entry_changed(self, widget, data=None):
 
461
        """Filter the rows for something."""
 
462
        text = widget.get_text().decode('utf8')
 
463
        text = self._prepare_to_filter(text)
 
464
        self.refresh_treeview(text)
 
465
 
426
466
    def on_main_window_delete_event(self, widget, event):
427
467
        """Still time to decide if want to close or not."""
428
468
        logger.info("Attempt to close the program")
615
655
        episode = self.programs_data[row[4]]  # 4 is the episode number
616
656
        logger.debug("Double click in %s", episode)
617
657
        if episode.state == Status.downloaded:
618
 
            self._play_episode(row)
 
658
            self._play_episode(episode)
619
659
        elif episode.state == Status.none:
620
660
            self._queue_download(row)
621
661