def post_to_tumblr(self, title, url): api = Api(BLOG, USER, PASSWORD) try: html = '<img src="%s" alt="%s" />' % (url, title) api.write_regular(title, html) except TumblrError, e: logging.error(e)
def testBadAuthenticate(self): api = Api(BLOG, USER, 'badpassword') try: api.auth_check() assert False # should never get here except TumblrAuthError, e: pass
def testBadAuthenticate(self): api = Api(BLOG, USER, 'badpassword' ) try: api.auth_check() assert False # should never get here except TumblrAuthError, e: pass
def image_posts_with_tags(blogname): ''' given the url for a blog, returns a list of all the Image posts that have tags. ''' api = Api(blogname) imgPosts = api.read(type='photo') return filter(lambda x: 'tags' in x, imgPosts)
def force_update(self, request, tumblr_queryset): ''' Force an update of the tumblr item, including it's tags by deleting the item and creating a new one from the tumblrapi as data-source. function iterates over query_set and can handle multiple checked items. *note: Design decision was made to use delete then create, as opposed to an standard update because of tags. In order to do a pure update method this could be refactored to overload(set) the model data_fields with data from api and then call .clear() on the tag field and then manually add the tags again. Or reconcile tags manually using remove/add Could be performance implications between write/delete vs. update. Though all calls to foreign-key on tags will result in write/delete. Additionally, this causes the id field on all sub-content-modals to increment, could cause integration issues with those that want static urls based on django id. this DOESNT change the tumblr_id however. ''' ## There is only one user now tumblr_user_name = settings.TUMBLR_USER_NAME tumbl_api = Api(tumblr_user_name + ".tumblr.com") for qs_object in tumblr_queryset: update_id = qs_object.tumblr_id tumbl_item = tumbl_api.read(id=update_id) ## ensure we have the new tumblr item data, and any additional verification ## then delete the old to make room to create the new qs_object.delete() # use the class method to triage content-types TumbleItem.create_new_item(tumbl_item['type'], tumbl_item)
def main(): if len(sys.argv) != 2: print "Usage: ./totumblr.py <photofile>" sys.exit(-1) photo_filename = sys.argv[1] parts = photo_filename.split('.') file_extension = parts[1] ftp = FTP('www.fakemachine.com') ftp.login('*****@*****.**','password') ftp.cwd('/domains/fakemachine.com/html/tumblrimages/') text = ftp.retrlines('list') m = re.search('\d+ matches', text) match = m.group(0) parts = match.split(' ') file_number = int(parts[0]) + 1 remote_filename = "%d.%s" % (file_number,file_extension) fp = open(photo_filename,'rb') ftp.storbinary('STOR %s' % remote_filename, fp) # Send the file fp.close() ftp.quit() image_url = "http://www.fakemachine.com/tumblrimages/%s" % remote_filename api = Api(BLOG,USER,PASSWORD) post = api.write_photo(source=image_url) print "Published: ", post['url']
def tumblr_text(request): conversation_id = request.POST['conversation_id'] title = request.POST['title'] body = request.POST['body'] # create a dictionary mapping names to random strings so they are unrecognizable but consistent replacements = generate_replacements() # strip credit card numbers credit_pattern = re.compile(r"\d{3,5}\D*\d{3,5}\D*\d{3,5}\D*\d{3,5}") body = credit_pattern.sub("XXXX-XXXX-XXXX-XXXX", body) # strip phone numbers phone_pattern = re.compile(r"(\d{3}\D*)?(\d{3})\D*(\d{4})") body = phone_pattern.sub("XXX-XXXX", body) # strip names #TODO: make sure names.txt is in correct directory relative to server names_path = os.path.dirname(__file__) + '/../names.txt' names = open(names_path, 'r') for name in names: name = name.rstrip() # remove newline name_pattern = re.compile(r"\b" + name + r"\b", re.IGNORECASE) body = name_pattern.sub(replacements[name], body) tumblr = Api(BLOG,USER,PASSWORD) post = tumblr.write_regular(title, body) return HttpResponse(title + "\n" + body)
def send_message(message): blog = settings.get('tumblr', 'blog') email = settings.get('tumblr', 'email') password = settings.get('tumblr', 'password') api = Api(blog, email, password) post = api.write_regular(title=None, body=message) print post['url']
def populate_models(self): ''' Import tumblr entries for the defined user in settings ''' tumblr_settings = { 'tumblr_user':settings.TUMBLR_USER_NAME, 'email':settings.TUMBLR_USER_EMAIL, 'password':settings.TUMBLR_USER_PASSWORD } if tumblr_settings['email'] != '' and tumblr_settings['password'] != '': self.log.info('email/pwd specified - attempting Authenticated read') tumblr_api = Api(name=tumblr_settings['tumblr_user'], email=tumblr_settings['email'], password=tumblr_settings['password']) tumbls = tumblr_api.authenticated_read(type=self.type) else: self.log.info('email/pwd *NOT* specified - attempting unauthenticated read') tumblr_api = Api(tumblr_settings['tumblr_user']) tumbls = tumblr_api.read(type=self.type) for tumbl in tumbls: self.log.debug(tumbl['type']) self.log.debug(tumbl['id']) self.log.debug(datetime.datetime.strptime(tumbl['date-gmt'], '%Y-%m-%d %H:%M:%S %Z')) if tumbl['type'] == 'regular': self.log.debug(tumbl['regular-title']) self.log.debug('--'*10) # use the class method to triage content-types TumbleItem.create_new_item(tumbl['type'], tumbl) self.log.info('import complete')
def read_blogs(blogs, download_dir): global config # Check if the download dir exists; if not create it if not os.path.exists(download_dir): os.mkdir(download_dir) # Process all given blogs for blog in blogs: # Check if the target dir exists; if not create it target_dir = os.path.join(download_dir, blog) if not os.path.exists(target_dir): os.mkdir(target_dir) print "Downloading images from " + blog + " to " + target_dir + "..." try: site_url = blog api = Api(site_url) posts = api.read(start=0, max=config.max_number_of_images) #posts = api.read(start=0) except: print "error" imageCounter = 1 for post in posts: try: url = post['photo-url-1280'] photo_caption = post['photo-caption'] slug = post['slug'] post_date_str = post['date-gmt'] except: print "error" image_name = url.rsplit('/', 1)[1] # Check if a file extension is given supported_file_types = ['jpg', 'jpeg', 'png', 'gif'] if not image_name[-3:] in supported_file_types: # Add an extension to the image name image_name = image_name + ".jpg" image_file_name = blog + "_-_" + image_name target_file_name = os.path.join(target_dir, image_file_name) # Check if file already exists if os.path.exists(target_file_name): print "Image already exists." imageCounter += 1 continue if imageCounter > config.max_number_of_images: break print "Downloading image Nr " + str(imageCounter) + ": \"" + image_file_name + "\" ..." download_image(url, target_file_name) imageCounter += 1
def blog(request): """ Blog page. Returns the embedded tumblr page. """ BLOG = 'jpglab.tumblr.com' api = Api(BLOG) post_list = api.read() return render_to_response('blog.html', RequestContext(request))
def testFixNames(self): api = Api(BLOG) before = {} before['test_one'] = 1 before['test_two'] = 1 after = api._fixnames(before) assert not 'test_one' in after assert 'test-one' in after assert 'test-two' in after assert not 'test_two' in after
def testEdit(self): api = Api(BLOG, USER, PASSWORD) newpost = api.write_regular('title','body') np = {} np['post-id'] = newpost['id'] np['regular-body'] = 'edited body' editedpost = api.write_regular(np) import pprint pp = pprint.PrettyPrinter(indent=4) pp.pprint(newpost) assert editedpost['regular-body'] == 'body'
def taglist(username): api = Api(username) posts = api.read() alltags = {} for post in posts: tags = post.get('tags', []) for tag in tags: try: alltags[tag][0] += 1 except KeyError: alltags[tag] = [1, post.get('date-gmt', '')] taglist = [tuple(val+[tag]) for tag,val in alltags.items()] return sorted(taglist, reverse=True)
def handle(self, *args, **options): tumblr_model = get_model('djumblr', 'Tumblr') tumblr_name = 'diegueus9' tumblr_email = '*****@*****.**' print 'working...' tumblr_api = Api(tumblr_name, tumblr_email, getpass.getpass('Your tumblr password:')) t, created = tumblr_model.objects.get_or_create( name=tumblr_name, email=tumblr_email) tumblr_response = tumblr_api.read() for post in tumblr_response: _(post)
def testRead(self): api = Api(BLOG) freq = {} posts = api.read() total = 0 for post in posts: total += 1 type = post['type'] try: freq[type] += 1 except: freq[type] = 1 assert total > 0 for type in freq: assert self.countType(api,type) == freq[type]
def testRead(self): api = Api(BLOG) freq = {} posts = api.read() total = 0 for post in posts: total += 1 type = post['type'] try: freq[type] += 1 except: freq[type] = 1 assert total > 0 for type in freq: assert self.countType(api, type) == freq[type]
def get_user_api(username): user = settings.TUMBLR_USERS[username] if user.has_key('email') and user.has_key('password'): return Api(user['tumblr_user'] + ".tumblr.com", user['email'], user['password']) else: return False
class LoginController(NSWindowController): blog = objc.IBOutlet() password = objc.IBOutlet() user = objc.IBOutlet() def init(self): self.errors = {'403':'Login o password incorrectos','404':'Tumblrlog incorrecto','urlopen':'no ingreso su tumblrlog'} return self @objc.IBAction def authTumblr_(self, sender): self.p = self.password.stringValue() self.u = self.user.stringValue() self.b = self.blog.stringValue() self.api = Api(self.b, self.u, self.p) NSLog("Blog %s, User %s , Password %s" % (self.b, self.u, self.p)) try: self.auth = self.api.auth_check() self.destroy() DashboardController.show() except tumblr.TumblrAuthError: print self.errors['403'] except tumblr.TumblrError(self): print self.errors['404'] #except urllib2.HTTPError(): # print self.errors['404'] #except urllib2.URLError: # print self.errors['urlopen'] def destroy(self): app = NSApplication.sharedApplication() appdelegate = app.delegate() appdelegate.w.close()
class Link(gui.CeFrame): def __init__(self, api): self.api = api gui.CeFrame.__init__(self, title="Opentumblr CE") self.l_link = gui.Label(self, "Add a Link", align = "center") self.l_name = gui.Label(self, "Name (optional)") self.tc_name = gui.Edit(self) self.l_url = gui.Label(self, "URL") self.tc_url = gui.Edit(self) self.l_description = gui.Label(self, "Description (optional)") self.tc_description = gui.Edit(self,multiline = True) self.b_create = gui.Button(self, "Create Post") self.b_cancel = gui.Button(self, "Cancel") self.b_create.bind(clicked = self.OnCreateLink) self.b_cancel.bind(clicked = self.OnCancel) self.__set_properties() self.__do_layout() def __set_properties(self): pass def __do_layout(self): s_link = gui.VBox(border = (5,5,5,5), spacing = 5) s_link.add(self.l_link) s_link.add(self.l_name) s_link.add(self.tc_name) s_link.add(self.l_url) s_link.add(self.tc_url) s_link.add(self.l_description) s_link.add(self.tc_description) s_link.add(self.b_create) s_link.add(self.b_cancel) self.sizer = s_link def OnCreateLink(self, evt): self.name = self.tc_name.get_text() self.url = self.tc_url.get_text() self.description = self.tc_description.get_text() if self.url: self.api = Api(self.api.name, self.api.email, self.api.password) try: self.post = self.api.write_link(self.name, self.url, self.description) except: print "Posteado en el primario" self.close() else: gui.Message.ok(title = 'Warning', caption = 'URL is required') def OnCancel(self, evt): self.close() #if __name__ == '__main__': # app = gui.Application(Link()) # app.run()
class Chat(gui.CeFrame): def __init__(self, api): self.api = api gui.CeFrame.__init__(self, title="Opentumblr CE") self.l_chat = gui.Label(self, "Add a Chat Post", align="center") self.l_title = gui.Label(self, "Title (optional)") self.tc_title = gui.Edit(self) self.l_dialogue = gui.Label(self, "Dialogue") self.l_example = gui.Label(self, "Example") self.l_tourist = gui.Label(self, "Tourist: Could you give us directions to Olive Garden") self.l_nyorker = gui.Label( self, "New Yorker: No, but I could give you directions to an actual Italian restaurant." ) self.tc_dialogue = gui.Edit(self, multiline=True) self.b_create = gui.Button(self, "Create Post") self.b_cancel = gui.Button(self, "Cancel") self.b_create.bind(clicked=self.OnCreateChat) self.b_cancel.bind(clicked=self.OnCancel) self.__set_properties() self.__do_layout() def __set_properties(self): pass def __do_layout(self): s_chat = gui.VBox(border=(5, 5, 5, 5), spacing=5) s_chat.add(self.l_chat) s_chat.add(self.l_title) s_chat.add(self.tc_title) s_chat.add(self.l_dialogue) s_chat.add(self.l_example) s_chat.add(self.l_tourist) s_chat.add(self.l_nyorker) s_chat.add(self.tc_dialogue) s_chat.add(self.b_create) s_chat.add(self.b_cancel) self.sizer = s_chat def OnCreateChat(self, evt): self.title = self.tc_title.get_text() self.conversation = self.tc_dialogue.get_text() if self.conversation: self.api = Api(self.api.name, self.api.email, self.api.password) try: self.post = self.api.write_conversation(self.title, self.conversation) except: print "Posteado en el primario" self.close() else: gui.Message.ok(title="Warning", caption="Dialogue is required") def OnCancel(self, evt): self.close()
class Video(gui.CeFrame): def __init__(self, api): self.api = api gui.CeFrame.__init__(self, title="Opentumblr CE") self.l_video = gui.Label(self, "Add a Video", align = "center") self.l_embed = gui.Label(self, "Embed a Video") self.tc_embed = gui.Edit(self) self.l_caption = gui.Label(self, "Caption (optional)") self.tc_caption = gui.Edit(self,multiline = True) self.b_create = gui.Button(self, "Create Post") self.b_cancel = gui.Button(self, "Cancel") self.b_create.bind(clicked = self.OnCreateVideo) self.b_cancel.bind(clicked = self.OnCancel) self.__set_properties() self.__do_layout() def __set_properties(self): pass def __do_layout(self): s_video = gui.VBox(border = (5,5,5,5), spacing = 2) s_video.add(self.l_video) s_video.add(self.l_embed) s_video.add(self.tc_embed) s_video.add(self.l_caption) s_video.add(self.tc_caption) s_video.add(self.b_create) s_video.add(self.b_cancel) self.sizer = s_video def OnCreateVideo(self, evt): self.embed = self.tc_embed.get_text() self.caption = self.tc_caption.get_text() if self.embed: self.api = Api(self.api.name, self.api.email, self.api.password) try: self.post = self.api.write_video(self.embed, self.caption) except: print "Posteado en el primario" self.close() else: gui.Message.ok(title = 'Warning', caption = 'Embed a video is required') def OnCancel(self, evt): self.close() #if __name__ == '__main__': # app = gui.Application(Video()) # app.run()
class Quote(gui.CeFrame): def __init__(self, api): self.api = api gui.CeFrame.__init__(self, title="Opentumblr CE") self.l_quote = gui.Label(self, "Add a Quote", align = "center") self.l_title = gui.Label(self, "Quote") self.tc_title = gui.Edit(self, multiline = True) self.l_source = gui.Label(self, "Source (optional)") self.tc_source = gui.Edit(self,multiline = True) self.b_create = gui.Button(self, "Create Post") self.b_cancel = gui.Button(self, "Cancel") self.b_create.bind(clicked = self.OnCreateQuote) self.b_cancel.bind(clicked = self.OnCancel) self.__set_properties() self.__do_layout() def __set_properties(self): pass def __do_layout(self): s_quote = gui.VBox(border = (5,5,5,5), spacing = 5) s_quote.add(self.l_quote) s_quote.add(self.l_title) s_quote.add(self.tc_title) s_quote.add(self.l_source) s_quote.add(self.tc_source) s_quote.add(self.b_create) s_quote.add(self.b_cancel) self.sizer = s_quote def OnCreateQuote(self, evt): self.quote = self.tc_title.get_text() self.source = self.tc_source.get_text() if self.quote: self.api = Api(self.api.name, self.api.email, self.api.password) try: self.post = self.api.write_quote(self.quote, self.source) except: print "Posteado en el primario" self.close() else: gui.Message.ok(title = 'Warning', caption = 'Quote is required') def OnCancel(self, evt): self.close() #if __name__ == '__main__': # app = gui.Application(Quote()) # app.run()
def OnAuthTumblr(self, evt): self.Blog = self.tc_blog.get_text() self.User = self.tc_mail.get_text() self.Password = self.tc_password.get_text() self.api = Api(self.Blog, self.User, self.Password) try: self.auth = self.api.auth_check() self.dashboard = Dashboard(self.api) except tumblr.TumblrAuthError: gui.Message.ok(title = 'Error', caption = 'Invalid email or password. Please try again')
def testRequiredArgs(self): api = Api(BLOG, USER, PASSWORD) self.assertRaises(TumblrError, api.write_regular) self.assertRaises(TumblrError, api.write_quote) self.assertRaises(TumblrError, api.write_photo) self.assertRaises(TumblrError, api.write_photo, source='foo', data='bar') self.assertRaises(TumblrError, api.write_conversation) self.assertRaises(TumblrError, api.write_link) self.assertRaises(TumblrError, api.write_video)
def update_backchannel(): """ Update data for the backchannel from Tumblr """ TUMBLR_FILENAME = 'www/tumblr.json' TUMBLR_BLOG_ID = 'nprbackchannel' TUMBLR_MAX_POSTS = 10 api = Api(TUMBLR_BLOG_ID) posts = list(api.read(max=TUMBLR_MAX_POSTS)) posts.reverse() with open(TUMBLR_FILENAME, 'w') as f: f.write(json.dumps(posts)) if 'settings' in env: conn = boto.connect_s3() bucket = conn.get_bucket(env.s3_bucket) key = Key(bucket) key.key = TUMBLR_FILENAME key.set_contents_from_filename( TUMBLR_FILENAME, policy='public-read', headers={ 'Cache-Control': 'max-age=5 no-cache no-store must-revalidate' }) if env.alt_s3_bucket: conn = boto.connect_s3() bucket = conn.get_bucket(env.alt_s3_bucket) key = Key(bucket) key.key = TUMBLR_FILENAME key.set_contents_from_filename( TUMBLR_FILENAME, policy='public-read', headers={ 'Cache-Control': 'max-age=5 no-cache no-store must-revalidate' })
def OnCreateChat(self, evt): self.title = self.tc_title.get_text() self.conversation = self.tc_dialogue.get_text() if self.conversation: self.api = Api(self.api.name, self.api.email, self.api.password) try: self.post = self.api.write_conversation(self.title, self.conversation) except: print "Posteado en el primario" self.close() else: gui.Message.ok(title="Warning", caption="Dialogue is required")
def OnCreatePost(self, evt): self.title = self.tc_title.get_text() self.body = self.tc_post.get_text() if self.body: self.api = Api(self.api.name, self.api.email, self.api.password) try: self.post = self.api.write_regular(self.title, self.body) except: print "Posteado en el primario" self.close() else: gui.Message.ok(title = 'Warning', caption = 'Post is required')
def OnCreateQuote(self, evt): self.quote = self.tc_title.get_text() self.source = self.tc_source.get_text() if self.quote: self.api = Api(self.api.name, self.api.email, self.api.password) try: self.post = self.api.write_quote(self.quote, self.source) except: print "Posteado en el primario" self.close() else: gui.Message.ok(title = 'Warning', caption = 'Quote is required')
def OnCreateVideo(self, evt): self.embed = self.tc_embed.get_text() self.caption = self.tc_caption.get_text() if self.embed: self.api = Api(self.api.name, self.api.email, self.api.password) try: self.post = self.api.write_video(self.embed, self.caption) except: print "Posteado en el primario" self.close() else: gui.Message.ok(title = 'Warning', caption = 'Embed a video is required')
def authTumblr_(self, sender): self.p = self.password.stringValue() self.u = self.user.stringValue() self.b = self.blog.stringValue() self.api = Api(self.b, self.u, self.p) NSLog("Blog %s, User %s , Password %s" % (self.b, self.u, self.p)) try: self.auth = self.api.auth_check() self.destroy() DashboardController.show() except tumblr.TumblrAuthError: print self.errors['403'] except tumblr.TumblrError(self): print self.errors['404']
def OnCreateLink(self, evt): self.name = self.tc_name.get_text() self.url = self.tc_url.get_text() self.description = self.tc_description.get_text() if self.url: self.api = Api(self.api.name, self.api.email, self.api.password) try: self.post = self.api.write_link(self.name, self.url, self.description) except: print "Posteado en el primario" self.close() else: gui.Message.ok(title = 'Warning', caption = 'URL is required')
def __init__(self, name, save='./photos', db='./tumblr_photo_down.db'): self.name = name self.save = save self.db = db self.api = Api(name + '.tumblr.com') self.pp = pprint.PrettyPrinter(indent=4) self._count = 0 self._coursor = 1 self.posts = None self.conn = None self._init_db() #self.pp.pprint(self.api); if os.path.isdir(save) is False: os.mkdir(save)
def update_backchannel(): """ Update data for the backchannel from Tumblr """ TUMBLR_FILENAME = 'www/tumblr.json' TUMBLR_BLOG_ID = 'nprbackchannel' TUMBLR_MAX_POSTS = 10 api = Api(TUMBLR_BLOG_ID) posts = list(api.read(max=TUMBLR_MAX_POSTS)) posts.reverse() with open(TUMBLR_FILENAME, 'w') as f: f.write(json.dumps(posts)) if 'settings' in env: conn = boto.connect_s3() bucket = conn.get_bucket(env.s3_bucket) key = Key(bucket) key.key = TUMBLR_FILENAME key.set_contents_from_filename( TUMBLR_FILENAME, policy='public-read', headers={'Cache-Control': 'max-age=5 no-cache no-store must-revalidate'} ) if env.alt_s3_bucket: conn = boto.connect_s3() bucket = conn.get_bucket(env.alt_s3_bucket) key = Key(bucket) key.key = TUMBLR_FILENAME key.set_contents_from_filename( TUMBLR_FILENAME, policy='public-read', headers={'Cache-Control': 'max-age=5 no-cache no-store must-revalidate'} )
class Login(gui.CeFrame): def __init__(self): gui.CeFrame.__init__(self, title="Opentumblr CE") self.l_tumblr = gui.Label(self, "Tumblr", align = "center") self.l_login = gui.Label(self, "Log in") self.l_mail = gui.Label(self, "Email address") self.tc_mail = gui.Edit(self) self.l_password = gui.Label(self, "Password") self.tc_password = gui.Edit(self, password = True) self.l_blog = gui.Label(self, "Blog") self.tc_blog = gui.Edit(self) self.b_login = gui.Button(self, "Login") self.b_login.bind(clicked = self.OnAuthTumblr) self.__set_properties() self.__do_layout() def __set_properties(self): pass def __do_layout(self): sizer_login = gui.VBox(border = (5,5,5,5), spacing = 5) sizer_login.add(self.l_tumblr) sizer_login.add(self.l_login) sizer_login.add(self.l_mail) sizer_login.add(self.tc_mail) sizer_login.add(self.l_password) sizer_login.add(self.tc_password) sizer_login.add(self.l_blog) sizer_login.add(self.tc_blog) sizer_login.add(self.b_login) self.sizer = sizer_login def OnAuthTumblr(self, evt): self.Blog = self.tc_blog.get_text() self.User = self.tc_mail.get_text() self.Password = self.tc_password.get_text() self.api = Api(self.Blog, self.User, self.Password) try: self.auth = self.api.auth_check() self.dashboard = Dashboard(self.api) except tumblr.TumblrAuthError: gui.Message.ok(title = 'Error', caption = 'Invalid email or password. Please try again')
def OnAuthTumblr(self, event): self.Blog = self.tc_blog.GetValue() #if not self.Blog: #self.Blog = '' #assert False,self.Blog #print "Conectado al blog primario: " self.User = self.cb_mail.GetValue() self.Password = self.tc_password.GetValue() self.api = Api(self.Blog, self.User, self.Password) #assert False,dir(self.api) try: self.auth = self.api.auth_check() self.dashboard = Dashboard(None, -1, self.api, self.path_images) self.dashboard.Show() self.Close() #print "Te haz logueado" except tumblr.TumblrAuthError: self.invalid = Invalid(self) self.invalid.Show() print errors['403'] except urllib2.HTTPError: print errors['404'] except urllib2.URLError: print errors['urlopen']
def testWrite(self): api = Api(BLOG, USER, PASSWORD) newpost = api.write_regular('title', 'body') post = api.read(newpost['id']) assert newpost['id'] == post['id'] newpost = api.write_link('http://www.google.com') post = api.read(newpost['id']) assert newpost['id'] == post['id'] newpost = api.write_quote('it was the best of times...') post = api.read(newpost['id']) assert newpost['id'] == post['id'] newpost = api.write_conversation('me: wow\nyou: double wow!') post = api.read(newpost['id']) assert newpost['id'] == post['id'] newpost = api.write_video('http://www.youtube.com/watch?v=60og9gwKh1o') post = api.read(newpost['id']) assert newpost['id'] == post['id'] newpost = api.write_photo( 'http://www.google.com/intl/en_ALL/images/logo.gif') post = api.read(newpost['id']) assert newpost['id'] == post['id']
def testAuthenticate(self): api = Api(BLOG, USER, PASSWORD) api.auth_check()
def populate_models(tumblr_user, user): ''' Takes a tumblr username (string), and a User model. Populates the tumblr models with data from 'tumblr_user'.tumblr.com, and associates the entries with 'user'. ''' tumbls = Api(tumblr_user + ".tumblr.com") for tumbl in tumbls.read(): # Common to all models id = tumbl['id'] pub_date = datetime.datetime.strptime(tumbl['date-gmt'], '%Y-%m-%d %H:%M:%S %Z') # 'Regular' objects. if tumbl['type'] == "regular": if tumbl['regular-title']: title = tumbl['regular-title'] else: title = "" body = tumbl['regular-body'] m = Regular(id=id, pub_date=pub_date, user=user, title=title, body=body) # 'Photo' objects. elif tumbl['type'] == "photo": source = tumbl['photo-url-250'] if tumbl['photo-caption']: caption = tumbl['photo-caption'] else: caption = "" m = Photo(id=id, pub_date=pub_date, user=user, source=source, caption=caption) # 'Quote' objects. elif tumbl['type'] == "quote": quote = tumbl['quote-text'] if tumbl['quote-source']: source = tumbl['quote-source'] else: source = "" m = Quote(id=id, pub_date=pub_date, user=user, quote=quote, source=source) # 'Link' objects. elif tumbl['type'] == "link": if tumbl['link-text']: name = tumbl['link-text'] else: name = "" url = tumbl['link-url'] if tumbl['link-description']: description = tumbl['link-description'] else: description = "" m = Link(id=id, pub_date=pub_date, user=user, name=name, url=url, description=description) # 'Conversation' objects. elif tumbl['type'] == "conversation": if tumbl['conversation-title']: title = tumbl['conversation-title'] else: title = "" m = Conversation(id=id, pub_date=pub_date, user=user, title=title, conversation_text=tumbl['conversation-text']) m.save() # 'Video' objects. elif tumbl['type'] == "video": embed = tumbl['video-player'] if tumbl['video-caption']: caption = tumbl['video-caption'] else: caption = "" m = Video(id=id, pub_date=pub_date, user=user, embed=embed, caption=caption) # 'Audio' objects. elif tumbl['type'] == "audio": embed = tumbl['audio-player'] if tumbl['audio-caption']: caption = tumbl['audio-caption'] else: caption = "" m = Audio(id=id, pub_date=pub_date, user=user, embed=embed, caption=caption) # TODO: Raise error. else: print "ERROR!", tumbl return '' m.save()
def write_mr_president_json(): """ Writes the JSON for Dear Mr. President to www. """ # # First, handle stuff from the V1 API. This is fetching the posts by tag. # print "V1: Starting." TUMBLR_FILENAME = 'www/live-data/misterpresident.json' TUMBLR_MAX_POSTS = 10000 MAX_PER_CATEGORY = 100 api = Api(app_config.TUMBLR_BLOG_ID) print "V1: API call made." posts = list(api.read(max=TUMBLR_MAX_POSTS)) print "V1: Fetched %s posts." % len(posts) print "V1: Starting to render." output = { 'idrathernotsayhowivoted': [], 'ivotedforyou': [], 'ididntvoteforyou': [], 'ididntvote': [], 'mostpopular': [] } for post in posts: simple_post = { 'id': post['id'], 'url': post['url'], 'text': post['photo-caption'], 'photo_url': post['photo-url-100'], 'photo_url_250': post['photo-url-250'], 'photo_url_500': post['photo-url-500'], 'photo_url_1280': post['photo-url-1280'], 'timestamp': post['unix-timestamp'] } for tag in post['tags']: try: if len(output[tag]) <= MAX_PER_CATEGORY: output[tag].append(simple_post) except KeyError: pass print "V1: Rendering finished." # # Now, fetch the most popular posts using the V2 API. # print "V2: Starting." # Set constants base_url = 'http://api.tumblr.com/v2/blog/inauguration2013.tumblr.com/posts/photo' key_param = '?api_key=Cxp2JzyA03QxmQixf7Fee0oIYaFtBTTHKzRA0AveHlh094bwDH' limit_param = '&limit=20' limit = 20 new_limit = limit post_list = [] # Figure out the total number of posts. r = requests.get(base_url + key_param) total_count = int(json.loads(r.content)['response']['total_posts']) print "V2: %s total posts available." % total_count # Do the pagination math. pages_count = (total_count / limit) pages_remainder = (total_count % limit) if pages_remainder > 0: pages_count += 1 pages = range(0, pages_count) print "V2: %s pages required." % len(pages) # Start requesting pages. # Note: Maximum of 20 posts per page. print "V2: Requesting pages." for page in pages: # Update all of the pagination shenanigans. start_number = new_limit - limit end_number = new_limit if end_number > total_count: end_number = total_count new_limit = new_limit + limit page_param = '&offset=%s' % start_number page_url = base_url + key_param + limit_param + page_param # Actually fetch the page URL. r = requests.get(page_url) posts = json.loads(r.content) for post in posts['response']['posts']: try: note_count = post['note_count'] post_list.append(post) except KeyError: pass # Sort the results first. print "V2: Finished requesting pages." print "V2: Sorting list." post_list = sorted(post_list, key=lambda post: post['note_count'], reverse=True) # Render the sorted list, but slice to just 24 objects per bb. print "V2: Rendering posts from sorted list." for post in post_list[0:24]: default_photo_url = post['photos'][0]['original_size']['url'] simple_post = { 'id': post['id'], 'url': post['post_url'], 'text': post['caption'], 'timestamp': post['timestamp'], 'note_count': post['note_count'], 'photo_url': default_photo_url, 'photo_url_250': default_photo_url, 'photo_url_500': default_photo_url, 'photo_url_1280': default_photo_url } # Handle the new photo assignment. for photo in post['photos'][0]['alt_sizes']: if int(photo['width']) == 100: simple_post['photo-url-100'] = photo['url'] if int(photo['width']) == 250: simple_post['photo_url_250'] = photo['url'] if int(photo['width']) == 500: simple_post['photo_url_500'] = photo['url'] if int(photo['width']) == 1280: simple_post['photo_url_1280'] = photo['url'] output['mostpopular'].append(simple_post) # Ensure the proper sort on our output list. print "V2: Ordering output." output['mostpopular'] = sorted(output['mostpopular'], key=lambda post: post['note_count'], reverse=True) # Write the JSON file. print "All: Producing JSON file at %s." % TUMBLR_FILENAME json_output = json.dumps(output) with open(TUMBLR_FILENAME, 'w') as f: f.write(json_output) print "All: JSON file written." if app_config.DEPLOYMENT_TARGET: with gzip.open(TUMBLR_FILENAME + '.gz', 'wb') as f: f.write(json_output) for bucket in app_config.S3_BUCKETS: conn = boto.connect_s3() bucket = conn.get_bucket(bucket) key = boto.s3.key.Key(bucket) key.key = '%s/live-data/misterpresident.json' % app_config.DEPLOYED_NAME key.set_contents_from_filename( TUMBLR_FILENAME + '.gz', policy='public-read', headers={ 'Cache-Control': 'max-age=5 no-cache no-store must-revalidate', 'Content-Encoding': 'gzip' } ) os.remove(TUMBLR_FILENAME + '.gz')