from urllib2 import urlopen
from xml.dom import minidom
from collections import defaultdict
import threading

from django.utils.translation import ugettext_lazy as _

from molly.apps.places.providers import BaseMapsProvider

class TubeRealtimeProvider(BaseMapsProvider):
    """
    Populates tube station entities with real-time departure information
    """
    
    TRACKERNET_STATUS_URL = 'http://cloud.tfl.gov.uk/TrackerNet/StationStatus'
    TRACKERNET_PREDICTION_URL = 'http://cloud.tfl.gov.uk/TrackerNet/PredictionDetailed/%s/%s'
    
    def get_statuses(self):
        statuses = {}
        xml = minidom.parseString(urlopen(self.TRACKERNET_STATUS_URL).read())
        for stationstatus in xml.getElementsByTagName('StationStatus'):
            name = stationstatus.getElementsByTagName('Station')[0].getAttribute('Name')
            status = stationstatus.getElementsByTagName('Status')[0].getAttribute('Description')
            status += ' ' + stationstatus.getAttribute('StatusDetails')
            statuses[name] = status
        return statuses
    
    def augment_metadata(self, entities, **kwargs):
        threads = []
        
        for entity in filter(lambda e: e.primary_type.slug == 'tube-station', entities):
            
            # Try and match up entity with StationStatus name
            for station, status in self.get_statuses().items():
                if entity.title.startswith(station):
                    entity.metadata['real_time_information'] = {
                        'pip_info': [status] if status != 'Open ' else [],
                    }
            if 'real_time_information' not in entity.metadata:
                entity.metadata['real_time_information'] = {}
            
            if 'london-underground-identifiers' in entity.metadata:
                thread = threading.Thread(target=self.get_times, args=[entity])
                thread.start()
                threads.append(thread)
        
        for thread in threads:
            thread.join()
    
    def get_times(self, entity):
        
        services = []
        
        station = entity.metadata['london-underground-identifiers']['station-code']
        for line in entity.metadata['london-underground-identifiers']['line-codes']:
            next_info = defaultdict(list)
            
            xml = minidom.parseString(urlopen(self.TRACKERNET_PREDICTION_URL % (line, station)).read())
            for tag in xml.getElementsByTagName('T'):
                next_info[tag.getAttribute('Destination')].append(int(tag.getAttribute('SecondsTo')))
            
            line_name = xml.getElementsByTagName('LineName')[0].childNodes[0].nodeValue[:-5]
            
            for dest, eta in next_info.items():
                services.append({
                    'service': line_name,
                    'destination': dest,
                    'etas': eta
                })
        
        services.sort(key=lambda s: s['etas'][0])
        for service in services:
            etas = [round(e/60) for e in service['etas']]
            # Translators: This refers to arrival times of trains, in minutes
            etas = [_('DUE') if e == 0 else _('%d mins') % e for e in etas]
            service['next'] = etas[0]
            service['following'] = etas[1:]
        entity.metadata['real_time_information']['services'] = services
        entity.metadata['meta_refresh'] = 30
@@ -2257,50 +2257,8 @@
 '%5D:%0A
-            next_info = defaultdict(list)%0A
     
@@ -2258,32 +2258,32 @@
 %5D:%0A            %0A
+
             xml 
@@ -2386,19 +2386,24 @@
     for 
-tag
+platform
  in xml.
@@ -2424,17 +2424,17 @@
 agName('
-T
+P
 '):%0A    
@@ -2458,53 +2458,157 @@
 info
-%5Btag.getAttribute('Destination')%5D.append(int(
+ = defaultdict(list)%0A                for tag in platform.getElementsByTagName('T'):%0A                    dest = '%25s (%25s)' %25 (%0A                        
 tag.
@@ -2625,21 +2625,22 @@
 te('
-SecondsTo')))
+Destination'),
 %0A   
@@ -2640,33 +2640,32 @@
 '),%0A            
-%0A
             line
@@ -2663,20 +2663,8 @@
     
- line_name =
  xml
@@ -2727,14 +2727,113 @@
 alue
-%5B:-5%5D%0A
+%0A                    )%0A                    next_info%5Bdest%5D.append(int(tag.getAttribute('SecondsTo')))%0A   
     
@@ -2832,33 +2832,38 @@
 %0A               
-%0A
+ %0A    
             for 
@@ -2902,32 +2902,36 @@
                 
+    
 services.append(
@@ -2952,16 +2952,20 @@
         
+   
+ 
 'service
@@ -2971,19 +2971,57 @@
 e': 
-line_name,%0A
+_('Plat %25d') %25 platform.getAttribute('Num'),%0A    
     
@@ -3077,16 +3077,20 @@
         
+    
 'etas': 
@@ -3093,16 +3093,20 @@
 s': eta%0A
+    
         
@@ -3574,16 +3574,16 @@
 ervices%0A
-
         
@@ -3618,8 +3618,9 @@
 h'%5D = 30
+%0A

Make tube RTI show platform as service number