2016-06-30 83 views
2

我正在使用Tweepy,一個推特python庫,django-storagesboto。我有一個自定義的manage.py命令,可以在本地正常工作,它從文件系統獲取圖像併發送圖像。但是,如果我將存儲更改爲Amazon S3,則無法訪問該文件。它給了我這個錯誤:Django Tweepy無法訪問Amazon S3文件

raise TweepError('Unable to access file: %s' % e.strerror) 

我試圖讓鬥中的圖像「公開」。沒有工作。這是代碼(它的工作原理沒有S3):

filename = model_object.image.file.url 
media_ids = api.media_upload(filename=filename) # ERROR 

params = {'status': tweet_text, 'media_ids': [media_ids.media_id_string]} 
api.update_status(**params) 

這條線:

model_object.image.file.url 

給我我想要的鳴叫圖像的完整URL,這樣的事情:

https://criptolibertad.s3.amazonaws.com/OrillaLibertaria/195.jpg?Signature=xxxExpires=1467645897&AWSAccessKeyId=yyy

我也嘗試過手動構建網址,因爲它是存儲在我的存儲桶中的公共圖像,如下所示:

filename = "https://criptolibertad.s3.amazonaws.com/OrillaLibertaria/195.jpg" 

但它不起作用。

¿爲什麼我得到Unable to access file錯誤?

從tweepy源代碼如下所示:

def media_upload(self, filename, *args, **kwargs): 
    """ :reference: https://dev.twitter.com/rest/reference/post/media/upload 
     :allowed_param: 
    """ 
    f = kwargs.pop('file', None) 
    headers, post_data = API._pack_image(filename, 3072, form_field='media', f=f) # ERROR 
    kwargs.update({'headers': headers, 'post_data': post_data}) 


def _pack_image(filename, max_size, form_field="image", f=None): 
     """Pack image from file into multipart-formdata post body""" 
     # image must be less than 700kb in size 
     if f is None: 
      try: 
       if os.path.getsize(filename) > (max_size * 1024): 
        raise TweepError('File is too big, must be less than %skb.' % max_size) 
      except os.error as e: 
       raise TweepError('Unable to access file: %s' % e.strerror) 

貌似Tweepy無法從亞馬遜S3存儲的圖像,但我怎樣才能使它發揮作用?任何建議都會有幫助。

+0

url是一種方法,而不是屬性。 –

+0

@BurhanKhalid我應該怎麼稱呼它?如果我做'model_object.image.file.url()'我得到的錯誤:''S3BotoStorageFile'對象沒有屬性'url'' – alejoss

+0

'model_object.image.url()' –

回答

2

時tweepy試圖在_pack_image獲得文件大小出現該問題:

if os.path.getsize(filename) > (max_size * 1024): 

功能os.path.getsize假定它被賦予磁盤上的文件路徑;然而,在你的情況下,它被給了一個URL。當然,這個文件在磁盤上找不到,並且os.error被引發。例如:

# The following raises OSError on my machine 
os.path.getsize('https://criptolibertad.s3.amazonaws.com/OrillaLibertaria/195.jpg') 

你可以做什麼來獲取文件內容,暫時保存在本地,然後加入Twitter:

import tempfile 


with tempfile.NamedTemporaryFile(delete=True) as f: 
    name = model_object.image.file.name 
    f.write(model_object.image.read()) 
    media_ids = api.media_upload(filename=name, f=f) 
    params = dict(status='test media', media_ids=[media_ids.media_id_string]) 
    api.update_status(**params) 

爲方便起見,我在這裏發表了一個有效的例子:https://github.com/izzysoftware/so38134984

+0

感謝您的答覆兄弟。我有一個問題,但。我一直在嘗試幾個小時來完成這項工作。我的代碼現在與您的代碼相同,但是,我仍然收到錯誤「無法訪問文件」。你可以看到我的整個項目在這個回購,確切的線路在這裏:https://github.com/Alejoss/CrHisoka/blob/master/hisoka/management/commands/tweet.py。爲什麼我會收到錯誤?我沒有任何線索。但是我懷疑f.write(model_object.image.read())'後面的'f'是'None'。有任何想法嗎? – alejoss

+0

我不認爲f可以沒有;也許它是空的?你的代碼看起來很穩定,今晚晚些時候我會試着檢查一下,然後試試看。您可能需要檢查您的aws用戶是否擁有s3燙髮號碼 – tutuDajuju

+0

我已經設法使用您的代碼上傳媒體和推文,請參閱PR中的詳細信息:https://github.com/Alejoss/CrHisoka/pull/1 。 – tutuDajuju