Hi all,

I need some help regarding how to cancel the connection from my server using the urllib2 library. I want the database to stop writing the data away as soon as the connection has been cancelled. The allchannels_timer will be called when I hit the 'enter' button, which will wait one second before connecting to my server to download the xml file. I want to download to stop when i hit the backspace button but currently, the code continues as if nothing happened.

Here is my current code:

import urllib2
import StringIO
import sqlite3
import threading
from sqlite3 import dbapi2 as database
from xml.etree import ElementTree
import xml.etree.ElementTree as ET
from UserDict import DictMixin

#get actioncodes from keyboard.xml
ACTION_ENTER = 7
ACTION_BACKSPACE = 110

def cSetVisible(WiNdOw,iD,V=True): WiNdOw.getControl(iD).setVisible(V)

class MyClass(xbmcgui.WindowXML):
     def timer1_8percent(self):
         for i in range(1):
             time.sleep(1)
             self.getControl(4202).setLabel("8%")


     def timer1_12percent(self):
         for i in range(1):
             time.sleep(2)
             self.getControl(4202).setLabel("12%")


     def timer1_18percent(self):
         for i in range(1):
             time.sleep(3)
             self.getControl(4202).setLabel("18%")


     def allchannels_timer(self):
         for i in range(1):
             time.sleep(0.3)
             self.getControl(4202).setLabel("0%")

             #DOWNLOAD THE XML SOURCE HERE
             url = ADDON.getSetting('allchannel.url')
             req = urllib2.Request(url)
             response = urllib2.urlopen(req)
             data = response.read()
             response.close()
             profilePath = xbmc.translatePath(os.path.join('special://userdata/addon_data/script.tvguide', ''))
             self.getControl(4202).setLabel("1%")
             self.thread = threading.Thread(target=self.timer1_8percent)
             self.thread.setDaemon(True)
             self.thread.start()
             self.thread = threading.Thread(target=self.timer1_12percent)
             self.thread.setDaemon(True)
             self.thread.start()
             self.thread = threading.Thread(target=self.timer1_18percent)
             self.thread.setDaemon(True)
             self.thread.start()


             if os.path.exists(profilePath):
                 profilePath = profilePath + 'source.db'
                 con = database.connect(profilePath)
                 cur = con.cursor()
                 cur.execute('CREATE TABLE programs(channel TEXT, title TEXT, start_date TIMESTAMP, stop_date TIMESTAMP, description TEXT)')
                 con.commit()
                 con.close
                 tv_elem = ElementTree.parse(StringIO.StringIO(data)).getroot()
                 profilePath = xbmc.translatePath(os.path.join('special://userdata/addon_data/script.tvguide', ''))
                 profilePath = profilePath + 'source.db'
                 con = sqlite3.connect(profilePath)
                 cur = con.cursor()
                 channels = OrderedDict()

                 # Get the loaded data
                 for channel in tv_elem.findall('channel'):
                     channel_name = channel.find('display-name').text
                     for program in channel.findall('programme'):
                         title = program.find('title').text
                         start_time = program.get("start")
                         stop_time = program.get("stop")
                         cur.execute("INSERT INTO programs(channel, title, start_date, stop_date)" + " VALUES(?, ?, ?, ?)", [channel_name, title, start_time, stop_time])
                         con.commit()
                         con.close

                 print 'Channels store into database are now successfully!'
                 program = None
                 now = datetime.datetime.now()
                 #strCh = '(\'' + '\',\''.join(channelMap.keys()) + '\')'
                 cur.execute('SELECT channel, title, start_date, stop_date FROM programs WHERE channel')
                 getprogram_info = cur.fetchall()

                 for row in getprogram_info:
                     programming = row[0], row[1], row[2], row[3]
                     print programming
                     #print row[0], row[1], row[2], row[3]
                     #programming = row[0], row[1], row[2], row[3]
                     #programming = row[0], row[1], row[2], row[3]
                     #cur.close()


def onAction(self, action):
   img1_yellow = xbmc.getCondVisibility('Control.IsVisible(3)')

   if action == ACTION_BACKSPACE:
     if img1_yellow:
       cSetVisible(self,3,True)
       self.getControl(4202).setLabel("")
       #cancel the connection and close the database


  if action == ACTION_ENTER:
     if img1_yellow:
         cSetVisible(self,3,False)
         self.thread = threading.Thread(target=self.allchannels_timer)
         self.thread.setDaemon(True)
         self.thread.start()

Do you know how I can cancel the connection from my server so that the xml file will stop being downloaded. I would further like to know how i can prevent the data from being written in my database once the connection has been cancelled.

I would be very grateful for any help regarding my problem, some example code would be highly appreciated.

Thanks in advance.

@Lucaci Andrew: Thank you for your help, I have had a look but there are no such a thing to tell me what function I should use to close or kill the thread when I press on the backspace button?

I only know multiprocessing. The example below starts an infinite loop in a process and uses the terminate method to end the thread, which could also be tied to the backspace key, so perhaps you can adapt the program. You should consider experimenting with a simple example to get the terminate kinks worked out and then move on to the full program

import time
from multiprocessing import Process

class TestClass():
   def __init__(self):
      self.ctr = 0

   def test_f(self, name):
      while True:
         self.ctr += 1
         print "test_f", self.ctr
         time.sleep(0.5)

if __name__ == '__main__':
   CT=TestClass()
   p = Process(target=CT.test_f, args=('P',))
   p.start()

   ## sleep for 5 seconds and terminate
   time.sleep(5.0)
   p.terminate()

Also, note how the function in the class is called in the code above.

def onAction(self, action):

is not part of the class in the code you posted so calling
self.allchannels_timer will not work.

self.thread = threading.Thread(target=self.allchannels_timer)

Edited 2 Years Ago by woooee

@woooee: Thank you very much for your help which is much appreicate it.

Do I need to use like this?

def onAction(self, action):
   if action == ACTION_BACKSPACE:
     if img1_yellow:
       cSetVisible(self,3,True)
       self.getControl(4202).setLabel("")
       p = Process(target=CT.test_f, args=('P',))
       p.terminate()
       time.sleep(5.0)
  if action == ACTION_ENTER:
     if img1_yellow:
         cSetVisible(self,3,False)
         p = Process(target=CT.test_f, args=('P',))
         p.start()

If not could you please show me an example how I should use it in a proper way.

self.allchannels_timer will work because I will be using it for xbmc media application which it support python version 2.6. I have try it and it works perfect.

I need to use the start and terminate function under the ACTION_ENTER and ACTION_BACKSPACE code because I'm using it for keyboard control.

Hope you understand this.

Thanks!!!

Edited 2 Years Ago by mark103

Make sure to import on this one!

from msvcrt import getch

keypress = 0
stopDown = 0

def keys(TargetKey):
    while keypress = 0:
        key = getch()
        if key == TagetKey:
            stopDown = 1
            keypress = 1

keys(delete)
if stopDown == 1:
    pass
    #code to stop the download
This article has been dead for over six months. Start a new discussion instead.