Skip to content

Commit ce262be

Browse files
committed
add ucare cli utility, minor improvements to lib
1 parent 649b1c1 commit ce262be

File tree

11 files changed

+159
-84
lines changed

11 files changed

+159
-84
lines changed

pyuploadcare/__init__.py

+12-17
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,17 @@
1515

1616
from .file import File, LazyFile
1717

18-
uuid_regex = re.compile(r'[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}')
18+
uuid_regex = re.compile(r'[a-z0-9]{8}-(?:[a-z0-9]{4}-){3}[a-z0-9]{12}')
19+
1920

2021
class UploadCareException(Exception):
21-
def __init__(self, message, response=None):
22+
def __init__(self, response, data):
23+
message = 'Response status is %i. Data: %s' % (response.status, data)
2224
super(UploadCareException, self).__init__(message)
2325
self.response = response
26+
self.data = data
27+
2428

25-
2629
class UploadCare(object):
2730
def __init__(self, pub_key, secret, timeout=5, api_base="http://api.uploadcare.com/"):
2831
self.pub_key = pub_key
@@ -47,23 +50,22 @@ def file(self, file_serialized):
4750

4851
if file_serialized.startswith('http'):
4952
f._cached_url = file_serialized
50-
53+
5154
return f
5255

5356
def file_from_url(self, url):
5457
data = self.make_request('POST', '/files/download/', {'source_url': url})
5558
return LazyFile(data['id'], self)
5659

57-
58-
def make_request(self, verb, uri, data=None):
60+
def make_request(self, verb, uri, data=None):
5961
parts = [''] + filter(None, self.path.split('/') + uri.split('/')) + ['']
6062
uri = '/'.join(parts)
6163

6264
content = ''
63-
65+
6466
if data:
6567
content = json.dumps(data)
66-
68+
6769
content_type = 'application/json'
6870
content_md5 = hashlib.md5(content).hexdigest()
6971
date = email.utils.formatdate(usegmt=True)
@@ -77,7 +79,7 @@ def make_request(self, verb, uri, data=None):
7779
sign = hmac.new(str(self.secret),
7880
sign_string,
7981
hashlib.sha1).hexdigest()
80-
82+
8183
headers = {
8284
'Authentication': 'UploadCare %s:%s' % (self.pub_key, sign),
8385
'Date': date,
@@ -87,8 +89,6 @@ def make_request(self, verb, uri, data=None):
8789
con = httplib.HTTPConnection(self.host, self.port, timeout=self.timeout)
8890
con.request(verb, uri, content, headers)
8991

90-
# assert False
91-
9292
logger.debug('sent: %s %s %s' % (verb, uri, content))
9393

9494
response = con.getresponse()
@@ -102,9 +102,4 @@ def make_request(self, verb, uri, data=None):
102102
if response.status == 204: # No Content
103103
return
104104

105-
raise UploadCareException('Response status is %i. Data: %s' % (response.status, data),
106-
response=response)
107-
108-
109-
110-
105+
raise UploadCareException(response, data)

pyuploadcare/dj/forms.py

+10-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
from django.forms import Field, TextInput, Media
2-
from django.conf import settings
1+
from django.forms import Field, TextInput
32
from django.utils.safestring import mark_safe
43
from django.utils.translation import ugettext as _, get_language
54

@@ -12,8 +11,9 @@
1211

1312
AVAIL_ASSET_LANG = ('en', 'ru', 'pl')
1413

14+
1515
def get_asset_lang():
16-
'''returns a localized asset url '''
16+
"""returns a localized asset url"""
1717
lang = get_language()
1818
if lang.startswith('en'):
1919
lang = lang[:2]
@@ -33,16 +33,15 @@ class FileWidget(TextInput):
3333

3434
class Media:
3535
js = (get_asset_lang(),)
36-
3736

3837
def __init__(self, attrs=None):
3938
default_attrs = {'role': 'uploadcare-line-uploader',
4039
'data-public-key': UploadCare().pub_key,
4140
'data-override-style': 'float: left;'}
42-
43-
if attrs:
41+
42+
if attrs is not None:
4443
default_attrs.update(attrs)
45-
44+
4645
super(FileWidget, self).__init__(default_attrs)
4746

4847
def render(self, name, value, attrs):
@@ -52,17 +51,17 @@ def render(self, name, value, attrs):
5251
if isinstance(value, basestring):
5352
value = UploadCare().file(value)
5453

55-
if value.url():
56-
fname = '<a href="%s">%s</a>' % (value.url(), value.filename())
54+
if value.url:
55+
fname = '<a href="%s">%s</a>' % (value.url, value.filename)
5756
else:
58-
fname = '%s (%s)' % (value.filename(), _('unavail.'))
57+
fname = '%s (%s)' % (value.filename, _('unavail.'))
5958

6059
description = '<p>%s: %s</p>' % (_('File'), fname)
6160

6261
html = mark_safe(html + description)
6362

6463
return html
65-
64+
6665

6766
class FileField(Field):
6867
widget = FileWidget

pyuploadcare/dj/models.py

+3-7
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,19 @@ class FileField(models.Field):
1010

1111
description = "UploadCare file id/URI with cached data"
1212

13-
def __init__(self, *args, **kwargs):
14-
super(FileField, self).__init__(*args, **kwargs)
15-
16-
1713
def get_internal_type(self):
1814
return "TextField"
1915

2016
def to_python(self, value):
2117
if not value:
2218
return None
23-
19+
2420
if isinstance(value, basestring):
25-
return UploadCare().file(value)
21+
return UploadCare().file(value)
2622

2723
if isinstance(value, File):
2824
return value
29-
25+
3026
raise ValidationError('Invalid value for a field')
3127

3228
def get_prep_value(self, value):

pyuploadcare/dj/tests.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
import datetime
2-
31
from django.test import TestCase
4-
from django.conf import settings
52
from django import forms
63

74
from pyuploadcare.dj import forms as uc_forms
85

6+
97
class TestFormFields(TestCase):
108
def test_form_field(self):
119

pyuploadcare/file.py

+15-14
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import time
2-
import urllib
32
import logging
43

54
logger = logging.getLogger("pyuploadcare")
65

76

87
RESIZER_BASE = 'http://services.uploadcare.com/resizer/%(file_id)s/%(cmd_line)s/'
98

9+
1010
class LazyFile(object):
1111
def __init__(self, id, ucare):
1212
self.id = id
@@ -47,15 +47,15 @@ def __getattr__(self, name):
4747
return super(File, self).__getattr__(name)
4848

4949
def keep(self, wait=False):
50-
self._info = self.ucare.make_request('POST', self.api_uri(), {'keep': 1})
50+
self._info = self.ucare.make_request('POST', self.api_uri, {'keep': 1})
5151

5252
if wait:
5353
while not self.info['on_s3']:
5454
self.update_info()
5555
time.sleep(0.1)
5656

5757
def delete(self):
58-
self.ucare.make_request('DELETE', self.api_uri())
58+
self.ucare.make_request('DELETE', self.api_uri)
5959

6060
@property
6161
def info(self):
@@ -65,36 +65,40 @@ def info(self):
6565
return self._info
6666

6767
def update_info(self):
68-
self._info = self.ucare.make_request('GET', self.api_uri())
68+
self._info = self.ucare.make_request('GET', self.api_uri)
6969

70+
@property
7071
def api_uri(self):
7172
return '/files/%s/' % self.file_id
7273

7374
def serialize(self):
74-
"""Returns a string suitable to be stored somethere. It's either an URL (to save a request) or just file-id"""
75+
"""Returns a string suitable to be stored somewhere.
76+
It's either an URL (to save a request) or just file-id"""
7577

76-
if self._info and self.url():
77-
return self.url()
78+
if self._info and self.url:
79+
return self.url
7880

7981
return self.file_id
8082

83+
@property
8184
def url(self):
8285
if self._cached_url:
8386
return self._cached_url
8487

8588
return self.info['original_file_url']
8689

90+
@property
8791
def filename(self):
88-
if not self.url():
92+
if not self.url:
8993
return ''
9094

91-
return self.url().split('/')[-1]
95+
return self.url.split('/')[-1]
9296

9397
def resized(self, width=None, height=None, crop=False):
9498
dimensions = str(width or '')
9599

96100
if height:
97-
dimensions += 'x%i' % height
101+
dimensions += 'x%i' % height
98102

99103
chunks = [dimensions]
100104

@@ -107,8 +111,5 @@ def resized(self, width=None, height=None, crop=False):
107111

108112
def string_resized(self, cmd_line):
109113
cmd_line = cmd_line.replace('_', '/')
110-
111-
return RESIZER_BASE % {'file_id': self.file_id, 'cmd_line': cmd_line}
112-
113-
114114

115+
return RESIZER_BASE % {'file_id': self.file_id, 'cmd_line': cmd_line}

test_project/gallery/models.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
from pyuploadcare.dj import FileField
44

5-
# Create your models here.
5+
66
class Photo(models.Model):
77
title = models.CharField(max_length=255)
88
photo = FileField()
9+
10+
def __unicode__(self):
11+
return self.title

test_project/gallery/tests.py

-16
This file was deleted.

test_project/gallery/views.py

-1
This file was deleted.

test_project/settings.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,7 @@
150150

151151

152152
UPLOADCARE = {
153-
#'pub_key': '3aaee4d571b832736d722396bf541154f14aaa1f50e0199e374ba8edea84efb6',
154-
#'secret': 'eea670103077e50b0d22ddc8da92165a04ba20c43274506bdad27b7966199ac2',
155153
#'api_base': "http://0.0.0.0:8000/api/",
156-
'pub_key': 'd07d12ae31b52d365ed3570dd651201f737d673c130c15185d53057e3b903e06',
157-
'secret': '6c8986d5861262e3cf231d315555980381891117e8357ac60cc20418fd6bf15b'
154+
'pub_key': '--your key here--',
155+
'secret': '--your secret here--'
158156
}

test_project/urls.py

+1-10
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,8 @@
1-
from django.conf.urls.defaults import patterns, include, url
1+
from django.conf.urls import patterns, include, url
22

3-
# Uncomment the next two lines to enable the admin:
43
from django.contrib import admin
54
admin.autodiscover()
65

76
urlpatterns = patterns('',
8-
# Examples:
9-
# url(r'^$', 'test_project.views.home', name='home'),
10-
# url(r'^test_project/', include('test_project.foo.urls')),
11-
12-
# Uncomment the admin/doc line below to enable admin documentation:
13-
# url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
14-
15-
# Uncomment the next line to enable the admin:
167
url(r'^admin/', include(admin.site.urls)),
178
)

0 commit comments

Comments
 (0)