Skip to content

Instantly share code, notes, and snippets.

@d33tah
Created September 27, 2010 21:08
Show Gist options
  • Select an option

  • Save d33tah/599839 to your computer and use it in GitHub Desktop.

Select an option

Save d33tah/599839 to your computer and use it in GitHub Desktop.
#!/usr/bin/python
# -*- coding: utf-8 -*-
from pynk import *
#from config import * #might as well be removed - defines only "login" and "password"
set_debug(True)
from time import sleep
import math
from PIL import Image
import os
import sys
import urllib
from panda3d.core import loadPrcFileData
from direct.showbase.DirectObject import DirectObject
from panda3d.core import Point2, Point3, TextNode, BitMask32, LineSegs, NodePath
from panda3d.core import CollisionRay, CollisionNode, CollisionTraverser, CollisionHandlerQueue, GeomNode
from direct.interval.FunctionInterval import Wait
from direct.gui.DirectGui import *
sys.path.insert(0,'')
def mul_tuple(x,y):
return tuple([y*t for t in x])
def scale_to_tex(tex):
xsize = tex.getXSize()
ysize = tex.getYSize()
if xsize > ysize:
yscale = float(ysize)/xsize
xscale = 1
else:
xscale = float(xsize)/ysize
yscale = 1
return (xscale,1,yscale)
def blinkTask(task):
if task.time < 0.1:
return task.cont
base.setBackgroundColor(*C_BLACK)
return task.done
def blink(str):
if str: debug(">>>> "+str+'\n')
base.setBackgroundColor(*C_RED)
taskMgr.add(blinkTask,'blink')
def photo_to_tex(nk,url):
filename = nk.cache_filename(url)
if not os.path.exists(filename+'.png'):
nk.get_url(url,cached=True)
file_from = open(filename,'rb')
file_to = open(filename+'.png','wb')
Image.open(file_from).save(file_to)
else:
debug("PPH: Found cache for %s\n" % url)
return loader.loadTexture(filename+'.png')
def loadObject(tex = None, pos = Point2(0,0), depth = 55, scale = 1, transparency = True,tag = []):
obj = loader.loadModel("square")
obj.reparentTo(camera)
obj.setPos(Point3(pos.getX(), depth, pos.getY()))
obj.setDepthTest(True)
obj.node().setIntoCollideMask(BitMask32.bit(1))
obj.setScale(scale)
obj.setTransparency(1)
if tex:
obj.setTexture(tex, 1)
for param in tag:
obj.node().setTag(param, str(tag[param]))
return obj
C_WHITE=(255,255,255)
C_BLACK=(0,0,0)
C_RED=(255,0,0)
C_GREEN=(0,255,0)
C_BLUE=(0,0,255)
C_PURPLE=(255,0,255)
C_YELLOW=(255,255,0)
C_CYAN=(0,255,255)
def drawLine(x0,y0,x1,y1,z=55,color=(255,255,255,1)):
line = LineSegs()
line.setColor(color)
line.moveTo(x0,z,y0)
line.drawTo(x1,z,y1)
param = line.create()
render.attachNewNode(param)
node = NodePath(param)
return node
class CenterTriangle:
def __init__(self,nk,size=13):
self.size = size
self.nk = nk
self.obj = loadObject(tex=loader.loadTexture('triangle.png'),
pos=Point2(0,0),
depth=60,
tag={'id':'center_triangle'},
scale=size)
def draw_url(self,url):
tex = photo_to_tex(self.nk,url)
self.obj.setTexture(tex)
scale = mul_tuple(scale_to_tex(tex),self.size)
self.obj.setScale(scale)
class ObjectsRing:
def __init__(self,world,r,nk):
self.world = world
self.r = r
self.nk = nk
self.objects = {}
self.task = None
def clear(self):
if self.task is not None:
taskMgr.remove(self.task)
self.task = None
for i in range(len(self.objects)):
self.objects[i].remove()
def drawObjectsTask(self,param,task):
global color_i
color_i = 0
n = len(param)
self.scale = min(2,abs(self.r/(float(n)/4.001 - 1 )))
for i in range(n):
deg=i*(6.2832/n)
x=math.sin(deg)*self.r
y=math.cos(deg)*self.r
object_ = self.drawObject(x,y,i,param[i])
if object_:
object_.setScale(self.scale)
self.objects[i]=object_
yield task.cont
def drawObjects(self,param):
self.task = taskMgr.add(self.drawObjectsTask, 'drawObjectsTask', extraArgs=[param], appendTask=True)
class ProfilesRing(ObjectsRing):
def __init__(self, *args,**kwargs):
self.profiles = {}
self.lines = []
ObjectsRing.__init__(self,*args,**kwargs)
def drawObject(self,x,y,i,profile):
self.profiles[i]=profile
try:
url = profile.get_details().avatar.thumb_url
except UserBannedError:
blink("User banned error")
return
except UserDeletedError:
blink("User deleted error")
return
else:
if not url:
blink("Thumbnail not found error")
return
his_friends = profile.get_friends()
#"""
counter_up = False
for my_friend in self.profiles.items():
if my_friend[1] in his_friends:
index = my_friend[0]
global color_i
colors = (C_RED,C_GREEN,C_BLUE,C_PURPLE,C_YELLOW,C_CYAN)
if not counter_up:
color_i += 1
counter_up = True
color = colors[color_i%len(colors)]+(1,)
try:
self.lines.append(drawLine(x,y,self.objects[index].getX(),self.objects[index].getZ(),color=color))
except AttributeError:
print("Problem connecting %s with %s" % ( profile.name, my_friend[1].name ) )
#"""
tex=photo_to_tex(self.nk,url)
return loadObject(pos=Point2(x,y),
tag={'id':'friendPhoto', 'number':i},
tex=tex,
scale=scale_to_tex(tex),
)
def clear(self, *args,**kwargs):
self.profiles = {}
for line in self.lines:
line.remove()
ObjectsRing.clear(self,*args,**kwargs)
class PhotosRing(ObjectsRing):
def __init__(self, *args,**kwargs):
self.photos = {}
ObjectsRing.__init__(self,*args,**kwargs)
def drawObject(self,x,y,i,photo):
self.photos[i] = photo
url = photo.thumb_url
tex=photo_to_tex(self.nk,url)
return loadObject(pos=Point2(x,y),
tag={'id':'galleryPhoto', 'number':i},
tex=tex,
scale=scale_to_tex(tex),
)
class World(DirectObject):
def __init__(self):
self.altText = OnscreenText("",
pos = (-1.3, -.95),
align = TextNode.ALeft,
mayChange = 1,
fg=C_RED+(1,),
)
#self.qt_app = QtGui.QApplication(sys.argv)
base.setBackgroundColor(*C_BLACK)
self.focusText = OnscreenText("Click some Image!",
fg=(1,1,1,1),
pos = (-1.3, .95, 56),
align = TextNode.ALeft,
mayChange = 1
)
self.nameText = OnscreenText("",
fg=(1,1,1,1),
pos = (-1.3, .90),
align = TextNode.ALeft,
mayChange = 1)
self.nk = PyNK()
self.nk.login(login,password)
self.nk.cache_cfg["PROFILE"] = True
self.nk.cache_cfg["FRIENDS_LIST"] = True
print self.nk.basic_auth
self.center_triangle = CenterTriangle(nk=self.nk)
self.profiles_ring = ProfilesRing(r=14,world=self,nk=self.nk)
self.photos_ring = PhotosRing(r=12,world=self,nk=self.nk)
if len(sys.argv)==2:
self.current_profile = NK_profile(nk=self.nk,url=sys.argv[1])
self.current_profile.get_details()
else:
self.current_profile = self.nk.my_profile
self.nameText.setText("Now viewing: %s" % self.current_profile.name )
self.my_friends = self.current_profile.get_friends()
#"""
print "selecting friends..."
little_friends = ( lambda friend: int(friend.get_details().photos_count) > 100 )
self.my_friends = list(reversed(sorted(self.my_friends, key=lambda friend: friend.friends_count)))
#friends = list(reversed(sorted(friends, key=lambda friend: friend.friends_count)))
#friends = [friend for friend in friends if little_friends(friend) ]
print "done (%s)" % len(self.my_friends)
#"""
self.profiles_ring.drawObjects(self.my_friends)
self.nk.logout()
self.nk.login(login,password)
self.control_setup()
self.collision_setup()
self.current_focus = None
self.mouseTask = taskMgr.add(self.mouseTask, 'mouseTask')
def mouseTask(self,task):
if not base.mouseWatcherNode.hasMouse(): return task.cont
obj = self.collision_test(force_id='friendPhoto')
if obj != self.current_focus:
if self.current_focus:
self.current_focus.setY(render,55)
self.current_focus.setScale(1)
if obj:
#obj.setY(render,54)
obj.setScale(render,3)
self.current_focus = obj
number = int(obj.findNetTag('id').getTag('number'))
profile = self.profiles_ring.profiles[number]
profile.get_details()
self.focusText.setText(profile.name)
else:
self.focusText.setText('Click some Image!')
return task.cont
def collision_setup(self):
self.pickerNode = CollisionNode('mouseRay')
self.pickerNP = camera.attachNewNode(self.pickerNode)
self.pickerRay = CollisionRay()
self.pickerNode.addSolid(self.pickerRay)
self.pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask())
self.collisionTraverser = CollisionTraverser()
self.handlerQueue = CollisionHandlerQueue()
self.collisionTraverser.addCollider(self.pickerNP, self.handlerQueue)
def control_setup(self):
self.accept('escape', sys.exit)
self.accept('q', sys.exit)
self.accept("mouse1", self.onLMB)
self.accept("mouse3", self.onRMB)
self.accept("alt-up", self.alt_up)
self.accept("alt", self.alt_down)
def alt_down(self):
self.altText = OnscreenText("ALT key pressed",
pos = (-1.3, -.95),
align = TextNode.ALeft,
mayChange = 1,
fg=C_RED+(1,),
)
def alt_up(self):
try:
if self.altText is not None:
self.altText.remove()
self.altText = None
except: pass #BUG ON WINDOWS
def collision_test(self,force_id=''):
mpos = base.mouseWatcherNode.getMouse()
self.pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY())
self.collisionTraverser.traverse(render)
if self.handlerQueue.getNumEntries() > 0:
self.handlerQueue.sortEntries()
pickedObj = self.handlerQueue.getEntry(0).getIntoNodePath()
if pickedObj:
if force_id:
obj_id = pickedObj.findNetTag('id').getTag('id')
if force_id != obj_id:
return None
return pickedObj
def onLMB(self):
if not base.mouseWatcherNode.hasMouse(): return
pickedObj = self.collision_test()
if pickedObj:
obj_id = pickedObj.findNetTag('id').getTag('id')
if obj_id=='friendPhoto':
number = int(pickedObj.findNetTag('id').getTag('number'))
profile = self.profiles_ring.profiles[number]
try:
url = profile.get_details().avatar.get_image_url()
except UserBannedError:
blink("User banned error")
return
except UserDeletedError:
blink("User deleted error")
return
if url is not None:
self.center_triangle.draw_url(url)
self.nameText.setText("%s (%s)" % (profile.name, profile.friends_count))
else:
blink("URL is empty")
self.photos_ring.clear()
self.nk.logout()
self.nk.login(login,password)
photos = profile.get_photos(first_only=False)
self.photos_ring.drawObjects(photos)
elif obj_id=='galleryPhoto':
#try:
number = int(pickedObj.findNetTag('id').getTag('number'))
url = self.photos_ring.photos[number].get_image_url()
self.center_triangle.draw_url(url)
#except AttributeError:
#base.setBackgroundColor(*C_RED)
#taskMgr.add(self.blink,'blink')
else:
pass
def onRMB(self):
if not base.mouseWatcherNode.hasMouse(): return
pickedObj = self.collision_test()
if pickedObj:
obj_id = pickedObj.findNetTag('id').getTag('id')
if obj_id=='friendPhoto':
number = int(pickedObj.findNetTag('id').getTag('number'))
profile = self.profiles_ring.profiles[number]
try:
friends = profile.get_friends()
except UserBannedError:
blink("User banned error")
return
except UserDeletedError:
blink("User deleted error")
return
self.nk.logout()
self.profiles_ring.clear()
self.photos_ring.clear()
self.nk.login(login,password)
self.profiles_ring.drawObjects(friends)
if __name__=='__main__':
from getpass import getpass
login = raw_input("Prosze podac swoj login na NK: ")
password = getpass("Prosze podac swoje haslo na NK (nie wyswietli sie):")
loadPrcFileData('','load-display wglGraphicsPipe')
loadPrcFileData('', 'window-title Panda3d - PyNK photo demo')
loadPrcFileData('', 'win-origin 50 0')
import direct.directbase.DirectStart
w = World()
run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment