下载文件并在python中取消 [英] downloading the file and cancel in python

查看:256
本文介绍了下载文件并在python中取消的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm working on my python script to download a xml file from my server and write the data in a sqlite3 database in parallel.

我需要一些有关如何使用urllib2库从服务器取消连接的帮助.我希望数据库在连接被取消后立即停止写数据.当用户单击输入"按钮时,将调用allchannels_timer,该按钮将等待一秒钟,然后再连接到我的服务器以下载xml文件.我想在按下Backspace按钮时停止下载,但是当前,代码继续运行,好像什么都没发生.

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 ahs been cancelled. The allchannels_timer will be called when the user hits 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.

这是我当前的代码:

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文件停止下载.我还想知道一旦取消连接,如何防止数据写入数据库.

Can someone please tell me 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.

推荐答案

要在后台下载文件,而在前台处理事件,则使用Process要简单得多.他们具有更好的Python支持,除了I/O之外还可以执行CPU,并且如果行动起来就可以杀死.

To download a file in the background, while processing events in the foreground, it's much simpler to use a Process. They have better Python support, they can do CPU in addition to I/O, and are killable if they act up.

以下将启动后台进程.父级的主循环会执行自己的操作,简要检查下载是否时时完成.如果下载完成,它将继续处理,然后退出.

The following starts a background process. The parent's main loop does its own thing, briefly checking if the download is done every now and then. If download is done, it continues processing, then exits.

玩得开心!

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

这篇关于下载文件并在python中取消的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆