2013-01-11 20 views
6

मैं उद्देश्य-सी से Ubutu वन एपीआई का उपयोग करने के लिए एक पायथन लाइब्रेरी बनाने की कोशिश कर रहा हूं। https://github.com/JoseExposito/U1-Finder-Plugin/blob/master/U1FinderLib/U1FinderLib.pyएक धागे में twisted reactor.run() निष्पादित करें?

मैं इस कारण मैं अपने रिएक्टर रन की एक बार के बजाय यह चल रहा है और यह उबंटू एक दस्तावेज के उदाहरण में बंद करो, की तरह करने की जरूरत के लिए, एपीआई के लिए कई कॉल करने के लिए की जरूरत है: यहाँ मेरी स्रोत कोड है : https://one.ubuntu.com/developer/files/store_files/syncdaemontool

क्योंकि यह संभव दो बार रिएक्टर को चलाने के लिए ... नहीं है और मैं() reactor.run निष्पादित करने के लिए एक सूत्र में क्योंकि मुझे लगता है कि पुस्तकालय का उपयोग करता है आवेदन नहीं रोक सकते हैं की जरूरत है!

ऐसा करना संभव है? मैं एक थ्रेड में रिएक्टर चलाने में सक्षम नहीं हूं और उबंटू वन एपीआई सिंक्रोनस को कॉल करता हूं।

संपादित करें:

मैं विचार का परीक्षण करने के लिए इस सरल स्रोत कोड का उपयोग कर रहा

:

#!/usr/bin/env python 
import objc 
import thread 
import os 
import time 
from twisted.internet import reactor, defer 
from ubuntuone.platform.tools import (SyncDaemonTool, is_already_running) 
from threading import Thread 
NSObject = objc.lookUpClass('NSObject') 

## 
# Variable to get the result of the calls to the Sync Daemon. 
# The result is a JSON string stored in returned_value[0]. 
returned_value = [''] 

## 
# Objective-C facade to the methods of the U1FinderLib. 
class U1FinderLib(NSObject): 

    def init(self): 
     self = super(U1FinderLib, self).init() 
     self.sync_daemon_tool = SyncDaemonTool(None) 
     Thread(target=reactor.run, args=(False,)).start() 
     return self 

    @objc.typedSelector('@@:') 
    def volumeList(self): 
     print "Begin volumeList" 
     reactor.callLater(0, run_command, "volume_list", [], self.sync_daemon_tool) 
     print "End volumeList" 
     return returned_value[0] 

## 
# Auxiliar functions to call to the sync daemon. 
@defer.inlineCallbacks 
def run_command(action, params, sync_daemon_tool): 
    print "run_command" 
    running = yield is_already_running() 
    print "After is_already_running" 
    try: 
     if not running: 
      returned_value[0] = '{ type:"error" reason:"Sync Daemon is not running" }' 
     else: 
      print "Before run_action" 
      yield run_action(action, params, sync_daemon_tool) 
      print "After run_action" 
    except Exception, e: 
     returned_value[0] = '{ type:"error" reason:"Exception: %s" }' % e 

@defer.inlineCallbacks 
def run_action(action, params, sync_daemon_tool): 
    if action == "volume_list": 
     d = sync_daemon_tool.get_folders() 
     returned_value[0] = yield d.addCallback(lambda r: volume_list(r)) 

# Volume List 
def volume_list(folders): 
    volumes_json = '{ type:"volume_list" volumes: { \n\t{ volume:"' + os.path.expanduser('~/Ubuntu One') + '" subscribed:"YES" }' 
    for folder in folders: 
     volumes_json += ',\n\t{ volume:"' + folder['path'] + '" subscribed:"' + ('YES' if bool(folder['subscribed']) else 'NO') + '" }' 
    volumes_json += '\n} }' 
    return volumes_json 

if __name__ == '__main__': 
    py = U1FinderLib.alloc().init() 
    print py.volumeList() 
    print "EXIT" 

और इस कार्यक्रम का उत्पादन होता है:

Begin volumeList 
End volumeList 

EXIT 

समस्या यह है कि है "run_command" फ़ंक्शन को कभी भी

+0

आप हमेशा अपने कार्यों को डिफ्रेंड के रूप में पंजीकृत कर सकते हैं, उन्हें रिएक्टर # –

+0

के माध्यम से आग लग सकते हैं क्या आप इसे थोड़ा सा समझा सकते हैं? मैं पाइथन पूरी तरह से नोब हूं (वास्तव में यह पायथन में मेरा पहला कोड है) – user1204395

+0

पायथन में पहली बार प्रोग्रामिंग और सीधे मुड़ने पर कूदते हैं? मैं आपको सभी भाग्य की कामना करता हूं ... :) –

उत्तर

15

किसी थ्रेड में रिएक्टर चलाने की बजाय कभी नहीं कहा जाता है, तो आप उस रिएक्टर का उपयोग करें जो उस एप्लिकेशन के साथ एकीकृत हो जिसे आप इसका उपयोग करना चाहते हैं।

उदाहरण के लिए, शायद आप CoreFoundation reactor का उपयोग करना चाहते हैं (क्योंकि आपका एप्लिकेशन ओबज-सी का उपयोग करता है और नाम में "खोजक" है)।

यदि आप वास्तव में ऐसा नहीं कर सकते हैं (उदाहरण के लिए, यदि उबंटू वन को एक अलग रिएक्टर की आवश्यकता होती है - मुझे नहीं पता कि यह मामला है), तो आप शायद उस रिएक्टर को थ्रेड में चला सकते हैं। अधिकांश रिएक्टर इसका समर्थन करते हैं, हालांकि अगर उबंटू वन को एक विशेष रिएक्टर की आवश्यकता होती है, तो रिएक्टर थ्रेडेड उपयोग का समर्थन नहीं कर सकता है।

आपने वास्तव में यह नहीं बताया कि थ्रेड में रिएक्टर चलाने की कोशिश करते समय आपको क्या समस्या है, इसलिए मैं यह समझने में आपकी सहायता नहीं कर सकता कि यह क्यों काम नहीं करता है। हालांकि, ऐसा करना आसान होना चाहिए। बस:

from twisted.internet import reactor 
from threading import Thread 

Thread(target=reactor.run, args=(False,)).start() 

ध्यान रखें कि एक बार आप, आप कर सकते हैं केवल उपयोग मुड़ एपीआई में है कि धागा एक सूत्र में रिएक्टर चलाने के लिए चुन रखें।

यदि यह काम नहीं करता है, तो यह आपके बारे में अधिक जानकारी प्रदान करता है कि यह आपके प्रश्न में कैसे काम नहीं करता है।

+0

आपकी मदद के लिए बहुत बहुत धन्यवाद। मैंने अपने प्रश्न में एक नमूना स्रोत कोड जोड़ा है। यदि मैं CFReactor का उपयोग करने का प्रयास करता हूं तो मेरे पास "CFNetwork नामक कोई मॉड्यूल नहीं है" त्रुटि है। मुझे कहना होगा कि मेरा आवेदन एक बंडल है जिसे मैं खोजक प्रक्रिया में इंजेक्ट करता हूं ताकि वे अपना व्यवहार बदल सकें और मैं कई विशेषताओं का उपयोग नहीं कर सकता। – user1204395

+0

क्या आपके पास अपने बंडल में सीएफनेटवर्क है? –

+0

हल, कोर फाउंडेशन रिएक्टर सही समाधान था। आपका बहुत बहुत धन्यवाद!! – user1204395

संबंधित मुद्दे