Skip to content

Instantly share code, notes, and snippets.

@binux
Last active Dec 14, 2015
Embed
What would you like to do?
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# vim: set et sw=4 ts=4 sts=4 ff=unix fenc=utf8:
# Author: Binux<17175297.hk@gmail.com>
# http://binux.me
# Created on 2012-12-15 16:11:13
import re
import json
import os.path
import logging
import requests
import tornado.web
import tornado.gen
import tornado.escape
import tornado.httpclient
from tornado.options import define, options
from pinterest import PinterestAPI
define("bind", default="0.0.0.0", help="addrs that debugger bind to")
define("port", default=8888, help="the port that debugger listen to")
define("debug", default=True, help="debug mode")
define("config", default="", help="config file")
define("username")
define("password")
define("pin_username")
define("pin_password")
define("board")
{
u'description': u'https://yande.re/post/show/246301',
u'title': u'bra breast_hold breasts charlotte_e_yeager michairu. miyafuji_yoshika nipples open_shirt strike_witches', u'post_status': u'publish',
u'user': u'binux',
u'pass': u'12345678',
u'categories': [u'reader']
}
yande_re = re.compile(r'https?://yande\.re/post/show/(\d+)')
danbooru_re = re.compile(r'https?://danbooru\.donmai\.us/posts/(\d+)')
konachan_re = re.compile(r'https?://konachan\.com/post/show/(\d+)')
class XMLRPCHandler(tornado.web.RequestHandler):
@property
def pinterest(self):
return self.application.pinterest
@property
def boards(self):
return self.application.boards
@tornado.web.asynchronous
@tornado.gen.engine
def get(self, show_page):
imgurl = yield tornado.gen.Task(self.download, show_page)
if not imgurl:
raise tornado.web.HTTPError(404)
self.finish('<html><body><img src="%s" /></body></html>' % imgurl)
#self.redirect(imgurl, permanent=True)
head = get
#@tornado.web.asynchronous
#@tornado.gen.engine
#def post(self, _):
#data = json.loads(self.request.body)
#self.finish()
#if options.username and data['user'] != options.username or options.password and data['pass'] != options.password:
#return
#imgurl = yield tornado.gen.Task(self.download, data['description'])
#if imgurl:
#logging.info((self.boards[options.board], data['title'], data['description'], imgurl))
#if not self.pinterest.add(self.boards[options.board], data['title'], data['description'], imgurl):
#self.pinterest.check_login()
def download(self, show_page, callback):
http = tornado.httpclient.AsyncHTTPClient()
m = None
for each in [yande_re, danbooru_re, konachan_re, ]:
m = each.match(show_page)
if m:
break
if not m:
callback(None)
return
show_page_id = m.group(1)
if each == danbooru_re:
http.fetch('http://danbooru.donmai.us/posts.json?tags=id:%s&login=roybinux&api_key=/ZzqkRfG.GL3fkJGAG2XI0zB8rEtVsSLMTkNZUyO' % show_page_id,
callback=lambda data: self._on_imgurl(each, callback, data))
elif each == yande_re:
http.fetch('https://yande.re/post.json?tags=id:%s' % show_page_id,
callback=lambda data: self._on_imgurl(each, callback, data))
elif each == konachan_re:
http.fetch('http://konachan.com/post.json?tags=id:%s' % show_page_id,
callback=lambda data: self._on_imgurl(each, callback, data))
else:
callback(None)
def _on_imgurl(self, each, callback, data):
data = tornado.escape.json_decode(data.body)[0]
if each == danbooru_re:
callback('http://danbooru.donmai.us/data/%s.%s' % (data['md5'], data['file_ext']))
elif each == yande_re or each == konachan_re:
callback(data.get('file_url', '').replace("yuno.yande.re", "yande.re") if data['file_size'] < 5 * 1024 * 1024 else (data.get('jpeg_url') or data.get('file_url', '')))
else:
callback(None)
class Application(tornado.web.Application):
def __init__(self):
handlers = [
('/(.*)', XMLRPCHandler),
]
settings = dict(
debug = options.debug,
gzip = True,
)
#self.pinterest = PinterestAPI()
#assert self.pinterest.login(options.pin_username, options.pin_password), 'login error'
#self.boards = self.pinterest.boards()
#assert options.board in self.boards, "can't find board %s" % options.board
super(Application, self).__init__(handlers, **settings)
if __name__ == "__main__":
import tornado.options
from tornado.ioloop import IOLoop
from tornado.httpserver import HTTPServer
tornado.options.parse_command_line()
if options.config:
tornado.options.parse_config_file(options.config)
tornado.options.parse_command_line()
http_server = HTTPServer(Application(), xheaders=True)
http_server.bind(options.port, options.bind)
http_server.start()
logging.info("http server started on %s:%s" % (options.bind, options.port))
IOLoop.instance().start()
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# vim: set et sw=4 ts=4 sts=4 ff=unix fenc=utf8:
# Author: Binux<i@binux.me>
# http://binux.me
# Created on 2013-03-15 16:39:39
import re
import json
import requests
class PinterestAPI(object):
def __init__(self):
self.reset()
def reset(self):
self.session = requests.Session()
self.session.headers.update({
'User-Agent': 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; en-us) AppleWebKit/531.21.8 (KHTML, like Gecko) Version/4.0.4 Safari/5 ',
})
def login(self, email, password):
r = self.session.get('https://pinterest.com/login/')
r.raise_for_status()
self.app_version = re.search(r'{"app_version": "(\w+)"}', r.text).group(1)
r = self.session.post('https://pinterest.com/resource/UserSessionResource/create/',
data={
'data': json.dumps({
'options': {
'username_or_email': email,
'password': password,
},
'context': {
'app_version': self.app_version,
}
}),
'source_url': '/login/',
},
headers = {
'Referer': 'https://pinterest.com/login/',
'X-CSRFToken': self.session.cookies['csrftoken'],
'X-NEW-APP': 1,
'X-Requested-With': 'XMLHttpRequest',
})
r.raise_for_status()
r = self.session.get('https://pinterest.com/')
if r.url == 'http://pinterest.com/':
self.username = re.search(r'"username": "(\w+)", ', r.text).group(1)
self.email = email
self.password = password
return True
return False
def add(self, board_id, description, link, image_url):
data = {
"options":{
"board_id":board_id,
"description":description,
"link":link,
"image_url":image_url,
"method":"scraped"
},
"context":{
"app_version":self.app_version,
}
}
r = self.session.post('http://pinterest.com/resource/PinResource/create/',
data = {
'data': json.dumps(data),
'source_url': '/',
'module_path': 'App()',
},
headers = {
'X-CSRFToken': self.session.cookies['csrftoken'],
'X-NEW-APP': 1,
'X-Requested-With': 'XMLHttpRequest',
})
r_json = json.loads(r.text)
return r_json['http_status'] == 200 and r_json['resource_response']['error'] is None
def boards(self):
data = {
"options":{},
"module":{
"name":"UserBoards",
"options":{
"username":self.username,
"secret_board_count":0
},
"append":False,
"errorStrategy":0
},
"context":{
"app_version":self.app_version,
}
}
r = self.session.get('http://pinterest.com/resource/NoopResource/get/', params={'data': json.dumps(data)})
assert json.loads(r.text)['http_status'] == 200, 'http_status == 200'
result = {}
def parse(tree):
if not tree.get('children'):
return
for each in tree['children']:
if each['name'] == 'ShowModalButton' and each.get('id') == 'boardCoverEditButton':
board = each['options']['submodule']['options']
result[board['board_name']] = board['board_id']
parse(each)
parse(json.loads(r.text)['module']['tree'])
return result
def get_info(self):
r = self.session.get('http://pinterest.com/resource/UserSettingsResource/get/')
if r.ok:
return json.loads(r.text)['resource_response']['data']
def check_login(self):
if self.get_info():
return True
else:
self.reset()
return self.login(self.email, self.password)
if __name__ == '__main__':
import os
p = PinterestAPI()
p.login(os.environ['PINTEREST_USER'], os.environ['PINTEREST_PASS'])
print p.check_login()
print p.get_info()
boards = p.boards()
print boards
print p.add(boards[boards.keys()[0]], '', '', '')
@sibinck
Copy link

sibinck commented Jul 5, 2013

Hello,

Currently "http://pinterest.com/resource/PinResource/" page is exist? I think that is not exist. So i have some issues for the pinterest pinning action. So please give me a solution.

Thanks

@mircobabini
Copy link

mircobabini commented May 3, 2014

What about the PinterestAPI class? Is it the official API package? Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment