下载文件并在python中取消

时间:2014-06-27 12:38:14

标签: python python-2.7 xbmc

我正在使用我的python脚本从我的服务器下载xml文件并将数据并行写入sqlite3数据库。

我需要一些关于如何使用urllib2库从我的服务器取消连接的帮助。我希望数据库在连接被取消后立即停止写入数据。当用户点击“输入”时,系统会调用allchannels_timer。按钮,在连接到我的服务器之前等待一秒钟以下载xml文件。当我点击退格按钮时,我想下载停止但是目前,代码仍然没有发生任何事情。

这是我目前的代码:

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()

有人可以告诉我如何从服务器取消连接,以便xml文件停止下载。我还想知道一旦取消连接,我怎么能阻止数据写入我的数据库。

我非常感谢有关我的问题的任何帮助,一些示例代码将受到高度赞赏。

1 个答案:

答案 0 :(得分:0)

要在后台下载文件,在前台处理事件时,使用Process要简单得多。他们有更好的Python支持,他们可以在I / O之外执行CPU,并且如果它们起作用,它们就可以运行。

以下开始后台进程。父主的循环做了自己的事情,简要检查下载是否偶尔完成。如果下载完成,则继续处理,然后退出。

玩得开心!

import logging, multiprocessing, time, urllib2

def download(url):
    mylog = multiprocessing.get_logger()
    mylog.info('downloading %s', url)
    time.sleep(2)
    req = urllib2.Request(url)
    response = urllib2.urlopen(req)
    data = response.read()
    response.close()
    # more here
    time.sleep(3)
    mylog.info('done')

def main():

    mylog = multiprocessing.log_to_stderr(level=logging.INFO)
    mylog.info('start')

    download_proc = multiprocessing.Process(
        target=download,
        args=('http://example.com',),
        )
    download_proc.start()

    while True:
        mylog.info('ding')
        if download_proc.join(timeout=0.1) is None:
            mylog.info('download done!')
            break
        time.sleep(1)

    mylog.info('done!')

if __name__=='__main__':
    main()

输出

[INFO/MainProcess] start
[INFO/MainProcess] ding
[INFO/Process-1] child process calling self.run()
[INFO/Process-1] downloading http://example.com
[INFO/MainProcess] download done!
[INFO/MainProcess] done!
[INFO/MainProcess] process shutting down
[INFO/MainProcess] calling join() for process Process-1
[INFO/Process-1] done
[INFO/Process-1] process shutting down
[INFO/Process-1] process exiting with exitcode 0