-
Notifications
You must be signed in to change notification settings - Fork 301
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This reverts commit 70cd050.
- Loading branch information
Showing
26 changed files
with
2,578 additions
and
27 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
# Form implementation generated from reading ui file 'creepy.ui' | ||
# | ||
# Created: Mon Mar 25 21:36:27 2013 | ||
# by: PyQt4 UI code generator 4.9.1 | ||
# | ||
# WARNING! All changes made in this file will be lost! | ||
|
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
SOURCES = creepy/CreepyMain.py | ||
TRANSLATIONS = creepy_en.ts creepy_gr.ts |
Large diffs are not rendered by default.
Oops, something went wrong.
Binary file not shown.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,205 @@ | ||
|
||
''' | ||
Copyright 2010 Yiannis Kakavas | ||
This file is part of creepy. | ||
creepy is free software: you can redistribute it and/or modify | ||
it under the terms of the GNU General Public License as published by | ||
the Free Software Foundation, either version 3 of the License, or | ||
(at your option) any later version. | ||
creepy is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU General Public License for more details. | ||
You should have received a copy of the GNU General Public License | ||
along with creepy If not, see <http://www.gnu.org/licenses/>. | ||
''' | ||
|
||
import urllib | ||
import flickrapi | ||
from flickrapi.exceptions import FlickrError | ||
import re | ||
from BeautifulSoup import BeautifulSoup as bs | ||
|
||
|
||
class Flickr(): | ||
""" | ||
Wrapper class for the Flickr API. | ||
provides functionality for user search and information retrieval | ||
""" | ||
|
||
def __init__(self, conf_file): | ||
|
||
self.api = flickrapi.FlickrAPI(conf_file['flickr']['api_key']) | ||
self.photo_dir = conf_file['directories']['profilepics_dir'] | ||
|
||
|
||
def search_real_name(self, input): | ||
""" | ||
Search user by real name | ||
Provides search function by real name. This is not provided by flickr API so | ||
it needs to be done the old(html-scrapping) way. | ||
Returns a list of user dictionaries | ||
""" | ||
html = urllib.urlopen("http://www.flickr.com/search/people/?see=none&q=" + input + "&m=names").read() | ||
''' | ||
Removing some javascript that choked BeautifulSoup's parser | ||
''' | ||
html = re.sub("(?is)(<script[^>]*>)(.*?)(</script>)", "", html) | ||
soup = bs(html) | ||
id = [] | ||
username = [] | ||
name = [] | ||
for r in soup.findAll('h2'): | ||
id_temp = r.a['href'].replace("/photos/", "")[:-1] | ||
if re.match(r'[\d]+@[A-Z][\d]+', id_temp): | ||
id.append(id_temp) | ||
else: | ||
id.append(self.getid_from_name(r.a.string)) | ||
username.append(r.a.string) | ||
try: | ||
name.append(r.next.next.next.next.b.string) | ||
except Exception: | ||
name.append("") | ||
pics = [p.img['src'] for p in soup.findAll(attrs={"class":"Icon"})] | ||
user_list = zip(id, username, name, pics) | ||
users = [] | ||
for user in user_list: | ||
try: | ||
temp_file = '%sprofile_pic_%s' % (self.photo_dir, user[0]) | ||
urllib.urlretrieve(user[3], temp_file) | ||
except Exception, err: | ||
pass | ||
#print 'Error retrieving %s profile picture' % (user[1]), err | ||
users.append({'id':user[0], 'username': user[1], 'realname':user[2], 'location':'' }) | ||
|
||
return users | ||
|
||
|
||
|
||
def search_user(self, input): | ||
""" | ||
Wrapper to the search function provided by flickr API | ||
Returns a list of user dictionaries | ||
""" | ||
|
||
if re.match("[\w\-\.+]+@(\w[\w\-]+\.)+[\w\-]+", input): | ||
try: | ||
results = self.api.people_findByEmail(find_email=input) | ||
except FlickrError: | ||
return | ||
else: | ||
try: | ||
results = self.api.people_findByUsername(username=input) | ||
except FlickrError, err: | ||
#print 'Error from flickr api ', err | ||
return | ||
if results.attrib['stat'] == "ok": | ||
user_list = [] | ||
#print results.find('user') | ||
for i in results.find('user').items(): | ||
user_list.append(self.get_user_info(i[1])) | ||
return user_list | ||
|
||
def getid_from_name(self, username): | ||
""" | ||
Gets user's nsid from flickr | ||
Returns user's nsid | ||
""" | ||
try: | ||
result = self.api.people_findByUsername(username=username) | ||
return result.find('user').attrib['nsid'] | ||
except FlickrError, err: | ||
return | ||
|
||
def get_user_info(self, id): | ||
""" | ||
Retrieves a user's username, real name and location as provided by flickr API | ||
Returns a user dictionary | ||
""" | ||
|
||
results = self.api.people_getInfo(user_id=id) | ||
if results.attrib['stat'] == 'ok': | ||
user = {'id':id, 'username':'', 'realname':'', 'location':''} | ||
res = results.find('person') | ||
user['username'] = res.find('username').text | ||
if res.find('realname'): | ||
user['realname'] = res.find('realname').text | ||
if res.find('location'): | ||
user['location'] = res.find('location').text | ||
return user | ||
|
||
|
||
def get_user_photos(self, id, page_nr): | ||
""" | ||
Retrieves a users public photos. | ||
Authentication and retrieval of protected photos is not yet implemented | ||
Returns a list with all the photos | ||
""" | ||
try: | ||
results = self.api.people_getPublicPhotos(user_id=id, extras="geo, date_taken", per_page=500, page=page_nr) | ||
if results.attrib['stat'] == 'ok': | ||
return results.find('photos').findall('photo') | ||
except Exception , err: | ||
conn_err = {'from':'flickr', 'tweetid':'', 'url': 'flickr' ,'error':err.message} | ||
self.errors.append(conn_err) | ||
|
||
|
||
def get_locations(self, photos): | ||
""" | ||
Determines location information from a list of photos | ||
Extracts the geo data provided by flickr API and returns a | ||
dictionary of locations | ||
""" | ||
locations = [] | ||
if photos: | ||
for photo in photos: | ||
if photo.attrib['latitude'] != '0': | ||
loc = {} | ||
loc['context'] = ('http://www.flickr.com/photos/%s/%s' % (photo.attrib['owner'], photo.attrib['id']), 'Photo from flickr \n Title : %s \n ' % (photo.attrib['title'])) | ||
loc['time'] = photo.attrib['datetaken'] | ||
loc['latitude'] = photo.attrib['latitude'] | ||
loc['longitude'] = photo.attrib['longitude'] | ||
loc['accuracy'] = photo.attrib['accuracy'] | ||
locations.append(loc) | ||
return locations | ||
|
||
def return_locations(self, id): | ||
""" | ||
Wrapper function for the location retrieval. | ||
Returns all the locations detected from the user's photos | ||
""" | ||
self.errors = [] | ||
locations_list = [] | ||
result_params = {} | ||
try: | ||
results = self.api.people_getPublicPhotos(user_id=id, extras="geo, date_taken", per_page=500) | ||
|
||
if results.attrib['stat'] == 'ok': | ||
res = results.find('photos') | ||
total_photos = res.attrib['total'] | ||
pages = int(res.attrib['pages']) | ||
#print "pages :" + str(pages) + " , total :" + total_photos | ||
if pages > 1: | ||
for i in range(1, pages + 1, 1): | ||
locations_list.extend(self.get_locations(self.get_user_photos(id, i))) | ||
else: | ||
locations_list.extend(self.get_locations(results.find('photos').findall('photo'))) | ||
|
||
except FlickrError, err: | ||
conn_err = {'from':'flickr_photos', 'tweetid':'', 'url': 'flickr' ,'error':err.message} | ||
self.errors.append(conn_err) | ||
result_params['flickr_errors'] = self.errors | ||
return (locations_list, result_params) |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
from PyQt4.QtCore import QVariant, QAbstractTableModel, Qt | ||
import os | ||
|
||
class InputPluginTable(QAbstractTableModel): | ||
def __init__(self, plugins, parents=None): | ||
super(InputPluginTable, self).__init__() | ||
self.plugins = plugins | ||
|
||
def rowCount(self, index): | ||
return len(self.targets) | ||
|
||
def columnCount(self, index): | ||
return 4 | ||
|
||
def headerData(self, section, orientation, role=Qt.DisplayRole): | ||
if role == Qt.TextAlignmentRole: | ||
if orientation == Qt.Horizontal: | ||
return QVariant(int(Qt.AlignLeft|Qt.AlignVCenter)) | ||
return QVariant(int(Qt.AlignRight|Qt.AlignVCenter)) | ||
if role != Qt.DisplayRole: | ||
return QVariant() | ||
if orientation == Qt.Horizontal: | ||
if section == 0: | ||
return QVariant("Plugin Name") | ||
elif section == 1: | ||
return QVariant("Author") | ||
elif section == 2: | ||
return QVariant("Version") | ||
elif section == 3: | ||
return QVariant("Description") | ||
return QVariant(int(section + 1)) | ||
|
||
|
||
def data(self, index, role): | ||
plugin = self.plugins[index.row()] | ||
if index.isValid() and (0 <= index.row() < len(self.plugins)) and plugin: | ||
column = index.column() | ||
if role == Qt.DisplayRole: | ||
if column == 0: | ||
return QVariant(plugin['name']) | ||
elif column == 1: | ||
return QVariant(plugin['author']) | ||
elif column == 2: | ||
return QVariant(plugin['version']) | ||
elif column == 3: | ||
return QVariant(plugin['description']) | ||
else: | ||
return QVariant() |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
[string_options] | ||
hgfhgf = ioa1sa | ||
sdsdss = test | ||
|
||
[boolean_options] | ||
bool1 = True | ||
bool2 = True | ||
|
||
[path_options] | ||
|
||
path1 = /home/ioannis/path1 | ||
path2 = /home/ioannis/path2 | ||
|
||
#Options to be used in runtime for location search | ||
# param_name = default_value | ||
[search_string_options] | ||
|
||
param_name1 = default_value1 | ||
param_name2 = default_value2 | ||
param_name3 = default_value3 | ||
|
||
[search_boolean_options] | ||
|
||
bool1 = True | ||
bool2 = True |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
from InputPlugin import InputPlugin | ||
import datetime | ||
|
||
class Dummy(InputPlugin): | ||
name = "dummy" | ||
configured = False | ||
hasWizard = False | ||
|
||
|
||
def __init__(self): | ||
pass | ||
def activate(self): | ||
pass | ||
|
||
def deactivate(self): | ||
pass | ||
|
||
def searchForTargets(self, search_term): | ||
return {'pluginName':'Dummy Plugin', 'targetUsername':'dummyusername', 'targetFullname': 'dummy fullname', 'targetPicture': '303ec0c.jpg', 'targetDetails': 'Profile description'} | ||
|
||
def loadConfiguration(self): | ||
pass | ||
|
||
def isFunctional(self): | ||
return True | ||
|
||
def returnLocations(self, target, search_params): | ||
d = datetime.datetime.strptime('2009-08-19 14:20:36 UTC', "%Y-%m-%d %H:%M:%S %Z") | ||
locations = [{'plugin': self.name,'lon':38.343242,'lat':23.3213,'context':'this is the context', 'shortName':'This is the short name','date':d},{'plugin': self.name,'lon':40.343242,'lat':29.3213,'context':'this is the context2', 'shortName':'This is the short name2', 'date':d}] | ||
return locations | ||
|
||
def returnPersonalInformation(self, search_params): | ||
pass | ||
|
||
def isConfigured(self): | ||
return (True,"") |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
[Core] | ||
Name = Dummy Plugin | ||
Module = dummy | ||
|
||
[Documentation] | ||
Author = Ioannis Kakavas | ||
Version = 0.1 | ||
Website = https://www.geocreepy.net | ||
Description = Returns a dummy list of locations |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
[string_options] | ||
infowindow_html = <div><div><h3>Retrieved from @PLUGIN@ </h3></div><div><p>Link to the original photo: @LINK@ <p><p>It was taken on : @DATE@ <p></div></div> | ||
api_key = d42d9307a0ee4d9f81962e651defef4f | ||
optiona = ioa6s | ||
|
||
[boolean_options] | ||
bool1 = True | ||
bool2 = True | ||
|
||
[path_options] | ||
|
||
path1 = /home/ioannis/path1 | ||
path2 = /home/ioannis/path2 | ||
|
||
#Options to be used in runtime for location search | ||
# param_name = default_value | ||
[search_string_options] | ||
|
||
param_name1 = default_value1 | ||
param_name2 = default_value2 | ||
param_name3 = default_value3 | ||
|
||
[search_boolean_options] | ||
|
||
bool1 = True | ||
bool2 = True |
Oops, something went wrong.