Advertisement
subixonfire

gui.py

Feb 3rd, 2012
354
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 20.40 KB | None | 0 0
  1. # -*- coding: UTF-8 -*-
  2.  
  3. import os
  4. import re
  5. import sys
  6. import xbmc
  7. import urllib
  8. import socket
  9. import xbmcvfs
  10. import xbmcgui
  11. import unicodedata
  12.  
  13. from utilities import *
  14.  
  15. STATUS_LABEL   = 100
  16. LOADING_IMAGE  = 110
  17. SUBTITLES_LIST = 120
  18. SERVICES_LIST  = 150
  19. CANCEL_DIALOG  = ( 9, 10, 92, 216, 247, 257, 275, 61467, 61448, )
  20.  
  21. _              = sys.modules[ "__main__" ].__language__
  22. __scriptname__ = sys.modules[ "__main__" ].__scriptname__
  23. __addon__      = sys.modules[ "__main__" ].__addon__
  24. __cwd__        = sys.modules[ "__main__" ].__cwd__
  25. __profile__    = sys.modules[ "__main__" ].__profile__
  26.  
  27. SERVICE_DIR    = os.path.join(__cwd__, "resources", "lib", "services")
  28.  
  29. class GUI( xbmcgui.WindowXMLDialog ):
  30.        
  31.   def __init__( self, *args, **kwargs ):        
  32.     pass
  33.  
  34.   def onInit( self ):
  35.     self.on_run()
  36.  
  37.   def on_run( self ):
  38.     if not xbmc.getCondVisibility("VideoPlayer.HasSubtitles"):
  39.       self.getControl( 111 ).setVisible( False )
  40.     try:
  41.       self.list_services()
  42.     except:
  43.       self.newWindow = False
  44.       self.list_services()
  45.      
  46.     try:
  47.       self.Search_Subtitles()
  48.     except:
  49.       errno, errstr = sys.exc_info()[:2]
  50.       xbmc.sleep(2000)
  51.       self.close()      
  52.  
  53.   def set_allparam(self):      
  54.     self.list           = []
  55.     service_list        = []
  56.     self.stackPath      = []
  57.     service             = ""    
  58.     self.newWindow      = True
  59.     self.temp           = False
  60.     self.rar            = False
  61.     self.stack          = False
  62.     self.autoDownload   = False
  63.     movieFullPath       = urllib.unquote(xbmc.Player().getPlayingFile())                # Full path of a playing file
  64.     path                = __addon__.getSetting( "subfolder" ) == "true"                 # True for movie folder
  65.     self.sub_folder     = xbmc.translatePath(__addon__.getSetting( "subfolderpath" ))   # User specified subtitle folder
  66.     self.year           = xbmc.getInfoLabel("VideoPlayer.Year")                         # Year
  67.     self.season         = str(xbmc.getInfoLabel("VideoPlayer.Season"))                  # Season
  68.     self.episode        = str(xbmc.getInfoLabel("VideoPlayer.Episode"))                 # Episode
  69.     self.mansearch      =  __addon__.getSetting( "searchstr" ) == "true"                # Manual search string??
  70.     self.parsearch      =  __addon__.getSetting( "par_folder" ) == "true"               # Parent folder as search string
  71.     self.language_1     = languageTranslate(__addon__.getSetting( "Lang01" ), 4, 0)     # Full language 1
  72.     self.language_2     = languageTranslate(__addon__.getSetting( "Lang02" ), 4, 0)     # Full language 2  
  73.     self.language_3     = languageTranslate(__addon__.getSetting( "Lang03" ), 4, 0)     # Full language 3
  74.     self.tmp_sub_dir    = os.path.join( __profile__ ,"sub_tmp" )                        # Temporary subtitle extraction directory  
  75.     self.stream_sub_dir = os.path.join( __profile__ ,"sub_stream" )                     # Stream subtitle directory    
  76.  
  77.     if ( movieFullPath.find("http://") > -1 ) or ( movieFullPath.find("https://") > -1 ): # added https by subixonfire
  78.       if not xbmcvfs.exists(self.stream_sub_dir):
  79.         os.makedirs(self.stream_sub_dir)
  80.       else:
  81.         rem_files(self.stream_sub_dir)
  82.       self.sub_folder = self.stream_sub_dir
  83.       self.temp = True
  84.  
  85. # start of my changes
  86.       if ( movieFullPath.find(".rapidshare.com/cgi-bin/rsapi.cgi") > -1 ):
  87.         self.rapidPath = movieFullPath.split("=")
  88.         movieFullPath = self.rapidPath[3]
  89.         self.rapidPath = movieFullPath.split("&dlauth")
  90.         movieFullPath = self.rapidPath[0]
  91. # end of my changes
  92. # subixonfire
  93.  
  94.     elif ( movieFullPath.find("rar://") > -1 ):
  95.       self.rar = True
  96.       self.temp = True
  97.       movieFullPath = movieFullPath[6:]
  98.       if path:
  99.         self.sub_folder = os.path.dirname(os.path.dirname( movieFullPath ))
  100.    
  101.     elif ( movieFullPath.find("stack://") > -1 ):
  102.       self.stackPath = movieFullPath.split(" , ")
  103.       movieFullPath = self.stackPath[0][8:]
  104.       self.stack = True
  105.  
  106.     if not path:
  107.       if len(self.sub_folder) < 1 :
  108.         self.sub_folder = os.path.dirname( movieFullPath )
  109.  
  110.     if path and not self.rar and not self.temp:
  111.       if self.sub_folder.find("smb://") > -1:
  112.         if self.temp:
  113.           dialog = xbmcgui.Dialog()
  114.           self.sub_folder = dialog.browse( 0, _( 766 ), "files")
  115.         else:
  116.           self.sub_folder = os.path.dirname( movieFullPath )
  117.       else:
  118.         self.sub_folder = os.path.dirname( movieFullPath )  
  119.    
  120.     if self.episode.lower().find("s") > -1:                                 # Check if season is "Special"            
  121.       self.season = "0"                                                     #
  122.       self.episode = self.episode[-1:]                                      #
  123.  
  124.     self.tvshow    = unicodedata.normalize('NFKD',
  125.                       unicode(unicode(xbmc.getInfoLabel
  126.                       ("VideoPlayer.TVshowtitle"), 'utf-8'))
  127.                       ).encode('ascii','ignore')                            # Show
  128.     self.title     = unicodedata.normalize('NFKD',
  129.                       unicode(unicode(xbmc.getInfoLabel
  130.                       ("VideoPlayer.Title"), 'utf-8'))
  131.                       ).encode('ascii','ignore')                            # Title
  132.  
  133.     if self.tvshow == "":
  134.       if str(self.year) == "":
  135.         title, season, episode = regex_tvshow(False, self.title)
  136.         if episode != "":
  137.           self.season = str(int(season))
  138.           self.episode = str(int(episode))
  139.           self.tvshow = title
  140.         else:
  141.           self.title, self.year = xbmc.getCleanMovieTitle( self.title )
  142.     else:
  143.       self.year = ""
  144.  
  145.     self.file_original_path = urllib.unquote ( movieFullPath )              # Movie Path
  146.  
  147.     if __addon__.getSetting( "disable_hash_search" ) == "true":
  148.       self.temp = True
  149.  
  150.     if (__addon__.getSetting( "fil_name" ) == "true"):                   # Display Movie name or search string
  151.       self.file_name = os.path.basename( movieFullPath )
  152.     else:
  153.       if (len(str(self.year)) < 1 ) :
  154.         self.file_name = self.title.encode('utf-8')
  155.         if (len(self.tvshow) > 0):
  156.           self.file_name = "%s S%.2dE%.2d" % (self.tvshow.encode('utf-8'), int(self.season), int(self.episode) )
  157.       else:
  158.         self.file_name = "%s (%s)" % (self.title.encode('utf-8'), str(self.year),)    
  159.  
  160.     if not xbmcvfs.exists(self.tmp_sub_dir):
  161.       os.makedirs(self.tmp_sub_dir)
  162.     else:
  163.       rem_files(self.tmp_sub_dir)
  164.  
  165.     if (__addon__.getSetting( "auto_download" ) == "true") and (__addon__.getSetting( "auto_download_file" ) != os.path.basename( movieFullPath )):
  166.         self.autoDownload = True
  167.         __addon__.setSetting("auto_download_file", "")
  168.  
  169.     for name in os.listdir(SERVICE_DIR):
  170.       if os.path.isdir(os.path.join(SERVICE_DIR,name)) and __addon__.getSetting( name ) == "true":
  171.         service_list.append( name )
  172.         service = name
  173.  
  174.     if len(self.tvshow) > 0:
  175.       def_service = __addon__.getSetting( "deftvservice")
  176.     else:
  177.       def_service = __addon__.getSetting( "defmovieservice")
  178.      
  179.     if service_list.count(def_service) > 0:
  180.       service = def_service
  181.  
  182.     if len(service_list) > 0:  
  183.       if len(service) < 1:
  184.         self.service = service_list[0]
  185.       else:
  186.         self.service = service  
  187.  
  188.       self.service_list = service_list
  189.       self.next = list(service_list)
  190.       self.controlId = -1
  191.       self.subtitles_list = []
  192.  
  193.       log( __name__ ,"Manual Search : [%s]"        % self.mansearch)
  194.       log( __name__ ,"Default Service : [%s]"      % self.service)
  195.       log( __name__ ,"Services : [%s]"             % self.service_list)
  196.       log( __name__ ,"Temp?: [%s]"                 % self.temp)
  197.       log( __name__ ,"Rar?: [%s]"                  % self.rar)
  198.       log( __name__ ,"File Path: [%s]"             % self.file_original_path)
  199.       log( __name__ ,"Year: [%s]"                  % str(self.year))
  200.       log( __name__ ,"Tv Show Title: [%s]"         % self.tvshow)
  201.       log( __name__ ,"Tv Show Season: [%s]"        % self.season)
  202.       log( __name__ ,"Tv Show Episode: [%s]"       % self.episode)
  203.       log( __name__ ,"Movie/Episode Title: [%s]"   % self.title)
  204.       log( __name__ ,"Subtitle Folder: [%s]"       % self.sub_folder)
  205.       log( __name__ ,"Languages: [%s] [%s] [%s]"   % (self.language_1, self.language_2, self.language_3,))
  206.       log( __name__ ,"Parent Folder Search: [%s]"  % self.parsearch)
  207.       log( __name__ ,"Stacked(CD1/CD2)?: [%s]"     % self.stack)
  208.  
  209.     return movieFullPath
  210.  
  211.   def Search_Subtitles( self, gui = True ):
  212.     self.subtitles_list = []
  213.     if gui:
  214.       self.getControl( SUBTITLES_LIST ).reset()
  215.       self.getControl( LOADING_IMAGE ).setImage( xbmc.translatePath( os.path.join( SERVICE_DIR, self.service, "logo.png") ) )
  216.  
  217.     exec ( "from services.%s import service as Service" % (self.service))
  218.     self.Service = Service
  219.     if gui:
  220.       self.getControl( STATUS_LABEL ).setLabel( _( 646 ) )
  221.     msg = ""
  222.     socket.setdefaulttimeout(float(__addon__.getSetting( "timeout" )))
  223.     try:
  224.       self.subtitles_list, self.session_id, msg = self.Service.search_subtitles( self.file_original_path, self.title, self.tvshow, self.year, self.season, self.episode, self.temp, self.rar, self.language_1, self.language_2, self.language_3, self.stack )
  225.     except socket.error:
  226.       errno, errstr = sys.exc_info()[:2]
  227.       if errno == socket.timeout:
  228.         msg = _( 656 )
  229.       else:
  230.         msg =  "%s: %s" % ( _( 653 ),str(errstr[1]), )
  231.     except:
  232.       errno, errstr = sys.exc_info()[:2]
  233.       msg = "Error: %s" % ( str(errstr), )
  234.     socket.setdefaulttimeout(None)
  235.     if gui:
  236.       self.getControl( STATUS_LABEL ).setLabel( _( 642 ) % ( "...", ) )
  237.  
  238.     if not self.subtitles_list:
  239.       if ((__addon__.getSetting( "search_next" )== "true") and (len(self.next) > 1)):
  240.         xbmc.sleep(1500)
  241.         self.next.remove(self.service)
  242.         self.service = self.next[0]
  243.         log( __name__ ,"Auto Searching '%s' Service" % (self.service,) )
  244.         self.Search_Subtitles(gui)
  245.       else:
  246.         self.next = list(self.service_list)
  247.         if gui:
  248.           if msg != "":
  249.             self.getControl( STATUS_LABEL ).setLabel( msg )
  250.           else:
  251.             self.getControl( STATUS_LABEL ).setLabel( _( 657 ) )
  252.           if self.newWindow:
  253.             window_list = SERVICES_LIST
  254.           else:
  255.             window_list = SUBTITLES_LIST
  256.             self.list_services()  
  257.           if gui:
  258.             self.setFocusId( window_list )
  259.             self.getControl( window_list ).selectItem( 0 )
  260.     else:
  261.       if not self.newWindow: self.list_services()
  262.       subscounter = 0
  263.       itemCount = 0
  264.       for item in self.subtitles_list:
  265.         if self.autoDownload and item["sync"] and  (item["language_name"] == languageTranslate(languageTranslate(self.language_1,0,2),2,0)):
  266.           self.Download_Subtitles(itemCount, True, gui)
  267.           __addon__.setSetting("auto_download_file", os.path.basename( self.file_original_path ))
  268.           return True
  269.           break
  270.         else:
  271.           if gui:
  272.             listitem = xbmcgui.ListItem( label=item["language_name"], label2=item["filename"], iconImage=item["rating"], thumbnailImage=item["language_flag"] )
  273.             if item["sync"]:
  274.               listitem.setProperty( "sync", "true" )
  275.             else:
  276.               listitem.setProperty( "sync", "false" )
  277.             self.list.append(subscounter)
  278.             subscounter = subscounter + 1                                    
  279.             self.getControl( SUBTITLES_LIST ).addItem( listitem )
  280.         itemCount += 1
  281.      
  282.       if gui:
  283.         self.getControl( STATUS_LABEL ).setLabel( '%i %s '"' %s '"'' % (len ( self.subtitles_list ), _( 744 ), self.file_name,) )
  284.         self.setFocusId( SUBTITLES_LIST )
  285.         self.getControl( SUBTITLES_LIST ).selectItem( 0 )
  286.       return False
  287.  
  288.   def Download_Subtitles( self, pos, auto = False, gui = True ):
  289.     if gui:
  290.       if auto:
  291.         self.getControl( STATUS_LABEL ).setLabel(  _( 763 ) )
  292.       else:
  293.         self.getControl( STATUS_LABEL ).setLabel(  _( 649 ) )
  294.     zip_subs = os.path.join( self.tmp_sub_dir, "zipsubs.zip")
  295.     zipped, language, file = self.Service.download_subtitles(self.subtitles_list, pos, zip_subs, self.tmp_sub_dir, self.sub_folder,self.session_id)
  296.     sub_lang = str(languageTranslate(language,0,2))
  297.  
  298.     if zipped :
  299.       self.Extract_Subtitles(zip_subs,sub_lang, gui)
  300.     else:
  301.       sub_ext  = os.path.splitext( file )[1]
  302.       sub_name = os.path.splitext( os.path.basename( self.file_original_path ) )[0]
  303.       if (__addon__.getSetting( "lang_to_end" ) == "true"):
  304.         file_name = "%s.%s%s" % ( sub_name, sub_lang, sub_ext )
  305.       else:
  306.         file_name = "%s%s" % ( sub_name, sub_ext )
  307.       file_from = file.replace('\\','/')
  308.       file_to = os.path.join(self.sub_folder, file_name).replace('\\','/')
  309.       # Create a files list of from-to tuples so that multiple files may be
  310.       # copied (sub+idx etc')
  311.       files_list = [(file_from,file_to)]
  312.       # If the subtitle's extension sub, check if an idx file exists and if so
  313.       # add it to the list
  314.       if ((sub_ext == ".sub") and (os.path.exists(file[:-3]+"idx"))):
  315.           log( __name__ ,"found .sub+.idx pair %s + %s" % (file_from,file_from[:-3]+"idx"))
  316.           files_list.append((file_from[:-3]+"idx",file_to[:-3]+"idx"))
  317.       for cur_file_from, cur_file_to in files_list:
  318.          subtitle_set,file_path  = copy_files( cur_file_from, cur_file_to )  
  319.       # Choose the last pair in the list, second item (destination file)
  320.       if subtitle_set:
  321.         xbmc.Player().setSubtitles(files_list[-1][1])
  322.         rem_files(self.tmp_sub_dir)
  323.         self.close()
  324.       else:
  325.         if gui:
  326.           self.getControl( STATUS_LABEL ).setLabel( _( 654 ) )
  327.           if self.newWindow:
  328.             window_list = SERVICES_LIST
  329.           else:
  330.             window_list = SUBTITLES_LIST
  331.             self.list_services()  
  332.           self.setFocusId( window_list )
  333.           self.getControl( window_list ).selectItem( 0 )  
  334.  
  335.   def Extract_Subtitles( self, zip_subs, subtitle_lang, gui = True ):
  336.     xbmc.executebuiltin('XBMC.Extract("%s","%s")' % (zip_subs,self.tmp_sub_dir,))
  337.     xbmc.sleep(1000)
  338.     files = os.listdir(self.tmp_sub_dir)
  339.     sub_filename = os.path.basename( self.file_original_path )
  340.     exts = [".srt", ".sub", ".txt", ".smi", ".ssa", ".ass" ]
  341.     subtitle_set = False
  342.     if len(files) < 1 :
  343.       if gui:
  344.         self.getControl( STATUS_LABEL ).setLabel( _( 654 ) )
  345.         if self.newWindow:  
  346.           self.setFocusId( SERVICES_LIST )
  347.           self.getControl( SERVICES_LIST ).selectItem( 0 )
  348.         else:
  349.           self.list_services()
  350.     else :
  351.       if gui:
  352.         self.getControl( STATUS_LABEL ).setLabel(  _( 652 ) )
  353.       subtitle_set = False
  354.       movie_sub = False
  355.       episode = 0
  356.       for zip_entry in files:
  357.         if os.path.splitext( zip_entry )[1] in exts:
  358.           subtitle_file, file_path = self.create_name(zip_entry,sub_filename,subtitle_lang)
  359.           if len(self.tvshow) > 0:
  360.             title, season, episode = regex_tvshow(False, zip_entry)
  361.             if not episode : episode = -1
  362.           else:
  363.             if os.path.splitext( zip_entry )[1] in exts:
  364.               movie_sub = True
  365.           if ( movie_sub or int(episode) == int(self.episode) ):
  366.             if self.stack:
  367.               try:
  368.                 for subName in self.stackPath:
  369.                   if (re.split("(?x)(?i)\CD(\d)", zip_entry)[1]) == (re.split("(?x)(?i)\CD(\d)", urllib.unquote ( subName ))[1]):
  370.                     subtitle_file, file_path = self.create_name(zip_entry,urllib.unquote ( os.path.basename(subName[8:]) ),subtitle_lang)
  371.                     subtitle_set,file_path = copy_files( subtitle_file, file_path )
  372.                 if re.split("(?x)(?i)\CD(\d)", zip_entry)[1] == "1":
  373.                   subToActivate = file_path
  374.               except:
  375.                 subtitle_set = False              
  376.             else:            
  377.               subtitle_set,subToActivate = copy_files( subtitle_file, file_path )
  378.  
  379.       if not subtitle_set:
  380.         for zip_entry in files:
  381.           if os.path.splitext( zip_entry )[1] in exts:
  382.             subtitle_file, file_path = self.create_name(zip_entry,sub_filename,subtitle_lang)
  383.             subtitle_set,subToActivate  = copy_files( subtitle_file, file_path )
  384.  
  385.     if subtitle_set :
  386.       xbmc.Player().setSubtitles(subToActivate)
  387.       self.close()
  388.     else:
  389.       if gui:
  390.         self.getControl( STATUS_LABEL ).setLabel( _( 654 ) )
  391.         if self.newWindow:
  392.           window_list = SERVICES_LIST
  393.         else:
  394.           window_list = SUBTITLES_LIST
  395.           self.list_services()  
  396.         self.setFocusId( window_list )
  397.         self.getControl( window_list ).selectItem( 0 )
  398.  
  399.   def create_name(self,zip_entry,sub_filename,subtitle_lang):
  400.     if (__addon__.getSetting( "lang_to_end" ) == "true"):
  401.       file_name = "%s.%s%s" % ( os.path.splitext( sub_filename )[0], subtitle_lang, os.path.splitext( zip_entry )[1] )
  402.     else:
  403.       file_name = "%s%s" % ( os.path.splitext( sub_filename )[0], os.path.splitext( zip_entry )[1] )
  404.     return os.path.join(self.tmp_sub_dir, zip_entry), os.path.join(self.sub_folder, file_name)
  405.  
  406.   def list_services( self ):
  407.     self.list = []
  408.     if self.newWindow:
  409.       window_list = SERVICES_LIST
  410.       win_label   = "%s"
  411.     else:
  412.       window_list = SUBTITLES_LIST  
  413.       win_label   = "[COLOR=FF0084ff]%s%s[/COLOR]" % (_( 610 ), "%s")
  414.  
  415.     self.getControl( window_list ).reset()
  416.  
  417.     for serv in self.service_list:
  418.       listitem = xbmcgui.ListItem( win_label % serv )
  419.       self.list.append(serv)
  420.       listitem.setProperty( "man", "false" )
  421.       self.getControl( window_list ).addItem( listitem )
  422.  
  423.     if self.mansearch :
  424.         listitem = xbmcgui.ListItem( win_label % _( 612 ) )
  425.         listitem.setProperty( "man", "true" )
  426.         self.list.append("Man")
  427.         self.getControl( window_list ).addItem( listitem )
  428.  
  429.     if self.parsearch :
  430.         listitem = xbmcgui.ListItem( win_label % _( 747 ) )
  431.         listitem.setProperty( "man", "true" )
  432.         self.list.append("Par")
  433.         self.getControl( window_list ).addItem( listitem )
  434.      
  435.     listitem = xbmcgui.ListItem( win_label % _( 762 ) )
  436.     listitem.setProperty( "man", "true" )
  437.     self.list.append("Set")
  438.     self.getControl( window_list ).addItem( listitem )    
  439.  
  440.   def keyboard(self, parent):
  441.     dir, self.year = xbmc.getCleanMovieTitle(self.file_original_path, self.parsearch)
  442.     if not parent:
  443.       kb = xbmc.Keyboard("%s (%s)" % (dir,self.year,), _( 751 ), False)
  444.       text = self.file_name
  445.       kb.doModal()
  446.       if (kb.isConfirmed()): text, self.year = xbmc.getCleanMovieTitle(kb.getText())
  447.       self.title = text
  448.     else:
  449.       self.title = dir  
  450.  
  451.     log( __name__ ,"Manual/Keyboard Entry: Title:[%s], Year: [%s]" % (self.title, self.year,))
  452.     if self.year != "" :
  453.       self.file_name = "%s (%s)" % (self.file_name, str(self.year),)
  454.     else:
  455.       self.file_name = self.title  
  456.     self.tvshow = ""
  457.     self.next = list(self.service_list)
  458.     self.Search_Subtitles()
  459.  
  460.   def onClick( self, controlId ):
  461.     if controlId == SUBTITLES_LIST:
  462.       if self.newWindow:
  463.         self.Download_Subtitles( self.getControl( SUBTITLES_LIST ).getSelectedPosition() )
  464.       else:
  465.         selection = str(self.list[self.getControl( SUBTITLES_LIST ).getSelectedPosition()])
  466.         if selection.isdigit():
  467.           log( __name__ , "Selected : [%s]" % (selection, ) )
  468.           self.Download_Subtitles( int(selection) )
  469.          
  470.     elif controlId == SERVICES_LIST:
  471.       xbmc.executebuiltin("Skin.Reset(SubtitleSourceChooserVisible)")
  472.       selection = str(self.list[self.getControl( SERVICES_LIST ).getSelectedPosition()])
  473.       self.setFocusId( 120 )
  474.    
  475.       if selection == "Man":
  476.         self.keyboard(False)
  477.       elif selection == "Par":
  478.         self.keyboard(True)
  479.       elif selection == "Set":
  480.         __addon__.openSettings()
  481.         self.set_allparam()
  482.         self.on_run()        
  483.       else:
  484.         self.service = selection
  485.         self.next = list(self.service_list)
  486.         self.Search_Subtitles()      
  487.  
  488.   def onFocus( self, controlId ):
  489.     self.controlId = controlId
  490.     try:
  491.       if controlId == 8999:
  492.         self.setFocusId( 150 )
  493.     except:
  494.       pass
  495.  
  496.   def onAction( self, action ):
  497.     if ( action.getId() in CANCEL_DIALOG):
  498.       self.close()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement