Created
September 27, 2010 21:08
-
-
Save d33tah/599839 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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