unity-scope-colourlovers-0.1+13.10.20130723/0000755000015700001700000000000012173421326020717 5ustar pbuserpbgroup00000000000000unity-scope-colourlovers-0.1+13.10.20130723/po/0000755000015700001700000000000012173421326021335 5ustar pbuserpbgroup00000000000000unity-scope-colourlovers-0.1+13.10.20130723/po/unity-scope-colourlovers.pot0000644000015700001700000000242112173420442027071 0ustar pbuserpbgroup00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-02-21 01:55+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #: ../src/unity_colourlovers_daemon.py:33 ../data/colourlovers.scope.in.h:4 msgid "Search COLOURlovers palettes, patterns and colors" msgstr "" #: ../src/unity_colourlovers_daemon.py:34 msgid "Sorry, there are no COLOURlovers results that match your search." msgstr "" #: ../src/unity_colourlovers_daemon.py:35 msgid "Powered by COLOURlovers" msgstr "" #: ../src/unity_colourlovers_daemon.py:43 msgid "Colours" msgstr "" #: ../data/colourlovers.scope.in.h:1 msgid "colourlovers;color;colors;patterns;pattern;palette;palettes;" msgstr "" #: ../data/colourlovers.scope.in.h:2 msgid "COLOURlovers" msgstr "" #: ../data/colourlovers.scope.in.h:3 msgid "Find COLOURlovers palettes, patterns and colors" msgstr "" unity-scope-colourlovers-0.1+13.10.20130723/po/POTFILES.in0000644000015700001700000000014112173420442023104 0ustar pbuserpbgroup00000000000000[encoding: UTF-8] src/unity_colourlovers_daemon.py [type: gettext/ini]data/colourlovers.scope.in unity-scope-colourlovers-0.1+13.10.20130723/MANIFEST.in0000644000015700001700000000007612173420442022456 0ustar pbuserpbgroup00000000000000include MANIFEST.in include src/* include data/* include po/* unity-scope-colourlovers-0.1+13.10.20130723/tests/0000755000015700001700000000000012173421326022061 5ustar pbuserpbgroup00000000000000unity-scope-colourlovers-0.1+13.10.20130723/tests/test_colourlovers.py0000644000015700001700000000700612173420442026231 0ustar pbuserpbgroup00000000000000#! /usr/bin/python3 # -*- coding: utf-8 -*- import imp import os import shutil import tempfile from unittest import TestCase from gi.repository import Unity class ResultSet(Unity.ResultSet): def __init__(self): Unity.ResultSet.__init__(self) self.results = [] def do_add_result(self, result): self.results.append({'uri':result.uri, 'title':result.title, 'comment':result.comment, 'icon':result.icon_hint}) class ScopeTestCase(TestCase): def init_scope(self, scope_path): self.scope_module = imp.load_source('scope', scope_path) self.scope = self.scope_module.load_scope() def perform_query(self, query, filter_set = Unity.FilterSet.new()): result_set = ResultSet() ctx = Unity.SearchContext.create(query, 0, filter_set, None, result_set, None) s = self.scope.create_search_for_query(ctx) s.run() return result_set class WallpaperTestScope(Unity.AbstractScope): def set_as_wallpaper(pattern): return class TestColourlovers(ScopeTestCase): def setUp(self): self.init_scope('src/unity_colourlovers_daemon.py') self.cache_dir = tempfile.mkdtemp() def tearDown(self): self.scope = None self.scope_module = None shutil.rmtree(self.cache_dir, ignore_errors=True) def test_valid_searches(self): self.scope_module.SEARCH_URI = 'file:tests/data/mock_colourlovers_pass#' expected_results = ['tiny paper umbrella', 'paparadsha', 'http://www.colourlovers.com/color/F8F671/tiny_paper_umbrella', 'http://www.colourlovers.com/img/F8F671/100/100/tiny_paper_umbrella.png'] results = [] for s in ['query']: result_set = self.perform_query(s) results.append(result_set.results[0]['title']) results.append(result_set.results[0]['comment']) results.append(result_set.results[0]['uri']) results.append(result_set.results[0]['icon']) self.assertEqual(results, expected_results) def test_preview(self): result = Unity.ScopeResult() result.title = 'Fancy Title' result.comment = 'author' result.icon_hint = 'http://www.colourlovers.com/img/fancy_pattern.png' scope = self.scope_module.Scope() previewer = scope.create_previewer(result, Unity.SearchMetadata()) self.assertEqual(previewer.run().props.title, result.title) self.assertEqual(previewer.run().props.subtitle, 'By '+result.comment) self.assertEqual(previewer.run().props.image_source_uri, result.icon_hint) def test_wallpaper_caching(self): self.scope_module.CACHE = self.cache_dir patterns = [] def set_as_wallpaper(pattern): patterns.append(pattern) self.scope.set_as_wallpaper = set_as_wallpaper self.scope.wallpaper_action('file:tests/data/ubuntu-raptor.png') local_path = os.path.join(self.cache_dir, 'ubuntu-raptor.png') self.assertEqual(os.path.isfile(local_path), True) self.assertEqual(patterns, [local_path]) def test_failing_search(self): self.scope_module.SEARCH_URI = 'file:tests/data/mock_colourlovers_fail#' for s in ['query']: result_set = self.perform_query(s) self.assertEqual(len(result_set.results), 0) if __name__ == '__main__': unittest.main() unity-scope-colourlovers-0.1+13.10.20130723/tests/data/0000755000015700001700000000000012173421326022772 5ustar pbuserpbgroup00000000000000unity-scope-colourlovers-0.1+13.10.20130723/tests/data/mock_colourlovers_fail0000644000015700001700000000000612173420442027451 0ustar pbuserpbgroup00000000000000 unity-scope-colourlovers-0.1+13.10.20130723/tests/data/ubuntu-raptor.png0000644000015700001700000001141712173420442026331 0ustar pbuserpbgroup00000000000000PNG  IHDR>asBIT|d pHYsjwtEXtSoftwarewww.inkscape.org<IDATx{tUկ$IH" @\ev]opV3;2Gd euYE92*APPH $$$t$HwWuWu99 U~W{Oe*Fc@1Pxhz6J{`+6[! q9 `2(Xlv{ŖՕ2|EQ> p$N6DA$E ,N4ׁW^qă q ,N^V!) q],n, xX-LOLej372L=|e@0`Q:0ZC q 2 ky\A`L+J<6bx(B @}#T!OK| 5]թ(O1a:CRJZ%LmEB(WbJy\6E`u{Šn>+Xˢk^ѯg"+9nxRu3U✠KY5zOFO;+h 4>-Y姓 Zׄ&PGkFp9FA$meOQhRc;5zW){i?*x> zuZZe ,>A4U~L}Z1k)B@ia@ r:9#'wYpZAm7"QϢb6*uܤ n]Zk؇Lk}7VQTn:˴h\i'py*(nNz:R7C؇@m?ĿKvo mzV1 tNG1oFp[~aH'if o߽o]ʎB0#i`*YĥIRk3]ӺsѶoi TOdzŁ}9I'i|o%=tAgf: @'v>4qh1ǟ?@Yr}e  y{[|0Iy4p*ƅ\(qvN|"$E]@n؇V> !׉%lj%Iqw{Z'6g&i`G|z|aDO䎛}HCGbzCbMC{ij=-_}BD E܋mиixL#t 0@A4a+ +p^:3[a7l4{ {XfT1@7%Ilv>7.CٍAh3Z(dJ%׉%/˫Knǫt:}tʎDV [i9r.qaqvS%!'3goIo-Fkk/c6 sp QQֲAJ˱d񗖤۵16gI1l!#'6KR|!_j0R͐3n+ՋnNׁ K*Ʊo4e @#m?|Cc 2Zd(N J-69_RUH!,XW ws챛u ݛn}D":U(Z\}(rqc6 )vaF~h/G\KhQP']ֆ+݁c8pOΨ䌞x-ŕo(Z nr7 țp99\Y{v4Z =$h,$)8/AkY&P7$}|DXɛ0+'O3Lxh<\NbW7">3f<~0]N ҄ yd&:~hezd|  Yשg'V.3ƊAO-(LJÚ"vjޤf֬jޅxi z AB`kYP@fie<^OkqbeV%JsFK o6c+ wܥ_`ajE7'k8MVX qh7z'kxƮګpb2Na'oM^+6 (\Mj*_v?[˱nw͹GSs:d8YkX X9#$Al@Ae֯7а޷Q)=(l#|8L,y޷T<Nf qI9* gk bP"nݶF^%@8n|WM2@Eb & m-*5?5!N+"GK'96? dO1:W$LL,y1 KO:j`uI߽sZj{m{']6,eTF F`{^8 fl^}#cTWoBbzbs yWFfj 8u}3 +y\o7K2CWtGqL1}A5y!S vh#?TW <}-[35jdRkS)Q<X]%kT2YX)c#ZL:\JƀoW}JDeTP R"NDJ5Rgw"ru7A f]H֢RoykqRS=S< Xkoϰro)QwQdF%fp20/E)dsq}JlaO~P԰nVݱ.gO%-q֘N?}Xjb xHY:@M6NS8. I 5~r>X @RS+8Qcs+%*yA?C8 L`fO?$h>kl)F䎍h^jLDWN䦄| Ā@LdB/RS}KS Jnҿ 3QC-@>k &E܁V +LnLKL `8z { !e*zq"qـ?s.$׻bSMrk*(Klr{EM;S5l&h.,K<p{E̓]6~B,Kj C_W@iM(O~^[ʫ0~>Z>_9{A(ӓ, eQP%?b6af!?2Ջ.X<1ځEq~JR~K Kl@YI!ME]B,$hf2 ;ɐ.'>29´Vl~"/A Da\i巸$Z<r`.|DFֱ ݻP@*Pg #:y\PZ x:nLe< P T xEˇgJ@ Ws'p0`qeJLՑ"sS@Wa.p+& fRk35qف(gfHqPlGm18r `20ꎢd؊Q37H # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License version 3, as published # by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranties of # MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . from gi.repository import Unity, UnityExtras from gi.repository import Gio, GLib import urllib.parse import urllib.request import json import gettext import os import datetime APP_NAME = 'unity-scope-colourlovers' LOCAL_PATH = '/usr/share/locale/' gettext.bindtextdomain(APP_NAME, LOCAL_PATH) gettext.textdomain(APP_NAME) _ = gettext.gettext CACHE = "%s/unity-scope-colourlovers/" % GLib.get_user_cache_dir() GROUP_NAME = 'com.canonical.Unity.Scope.Graphics.Colourlovers' UNIQUE_PATH = '/com/canonical/unity/scope/graphics/colourlovers' SEARCH_URI = "https://www.colourlovers.com/" SEARCH_HINT = _('Search COLOURlovers palettes, patterns and colors') NO_RESULTS_HINT = _('Sorry, there are no COLOURlovers results that match your search.') PROVIDER_CREDITS = _('Powered by COLOURlovers') SVG_DIR = '/usr/share/icons/unity-icon-theme/places/svg/' PROVIDER_ICON = SVG_DIR+'service-colourlovers.svg' DEFAULT_RESULT_ICON = SVG_DIR+'result-graphics.svg' DEFAULT_RESULT_MIMETYPE = 'text/html' DEFAULT_RESULT_TYPE = Unity.ResultType.DEFAULT c1 = {'id' :'top', 'name' :_('Colours'), 'icon' :SVG_DIR+'group-graphics.svg', 'renderer':Unity.CategoryRenderer.VERTICAL_TILE} CATEGORIES = [c1] FILTERS = [] m1 = {'id' :'description', 'type' :'s', 'field':Unity.SchemaFieldType.OPTIONAL} m2 = {'id' :'comment_nb', 'type' :'s', 'field':Unity.SchemaFieldType.OPTIONAL} m3 = {'id' :'rating', 'type' :'s', 'field':Unity.SchemaFieldType.OPTIONAL} m4 = {'id' :'date_created', 'type' :'s', 'field':Unity.SchemaFieldType.OPTIONAL} EXTRA_METADATA = [m1, m2, m3, m4] def search(search, filters): ''' Any search method returning results as a list of tuples. Available tuple fields: uri (string) icon (string) title (string) comment (string) dnd_uri (string) mimetype (string) category (int) result_type (Unity ResultType) extras metadata fields (variant) ''' results = [] if not search or len(search) < 2: return results search = urllib.parse.quote(search) for cat in ['patterns']: uri = '%sapi/%s?format=json&keywords=%s' % (SEARCH_URI, cat,search) try: req = urllib.request.Request(uri, headers={'User-Agent' : "Magic Browser"}) response = urllib.request.urlopen(req).read() data = json.loads(response.decode('utf-8')) except Exception as error: print(error) data = None if not data: return results for d in data: results.append({'uri':d['url'], 'icon':d['imageUrl'], 'title':d['title'], 'comment':d['userName'], 'description':d['description'], 'rating':str(d['numHearts']), 'date_created':str(d['dateCreated']), 'comment_nb':str(d['numComments'])}) return results # Classes below this point establish communication # with Unity, you probably shouldn't modify them. class MySearch (Unity.ScopeSearchBase): def __init__(self, search_context): super (MySearch, self).__init__() self.set_search_context (search_context) def do_run (self): ''' Adds results to the model ''' try: result_set = self.search_context.result_set for i in search(self.search_context.search_query, self.search_context.filter_state): if not 'uri' in i or not i['uri'] or i['uri'] == '': continue if not 'icon' in i or not i['icon'] or i['icon'] == '': i['icon'] = DEFAULT_RESULT_ICON if not 'mimetype' in i or not i['mimetype'] or i['mimetype'] == '': i['mimetype'] = DEFAULT_RESULT_MIMETYPE if not 'result_type' in i or not i['result_type'] or i['result_type'] == '': i['result_type'] = DEFAULT_RESULT_TYPE if not 'category' in i or not i['category'] or i['category'] == '': i['category'] = 0 if not 'title' in i or not i['title']: i['title'] = '' if not 'comment' in i or not i['comment']: i['comment'] = '' if not 'dnd_uri' in i or not i['dnd_uri'] or i['dnd_uri'] == '': i['dnd_uri'] = i['uri'] i['provider_credits'] = GLib.Variant('s', PROVIDER_CREDITS) result_set.add_result(**i) except Exception as error: print (error) class Preview (Unity.ResultPreviewer): def do_run(self): if self.result.metadata and 'description' in self.result.metadata and self.result.metadata['description'].get_string() != '': description = self.result.metadata['description'].get_string() else: description = '' preview = Unity.GenericPreview.new(self.result.title, description.strip(), None) preview.props.subtitle = _("By ") + self.result.comment preview.props.image_source_uri = self.result.icon_hint if self.result.metadata and 'date_created' in self.result.metadata and self.result.metadata['date_created'].get_string() != '': # Format date date = datetime.datetime.strptime(self.result.metadata['date_created'].get_string(), '%Y-%m-%d %H:%M:%S') translated_date = date.strftime('%x') preview.add_info(Unity.InfoHint.new("date_created", _("Created"), None, translated_date)) if self.result.metadata and 'comment_nb' in self.result.metadata and self.result.metadata['comment_nb'].get_string() != '': preview.add_info(Unity.InfoHint.new("comment_nb", _("Comments"), None, self.result.metadata['comment_nb'].get_string())) if self.result.metadata and 'rating' in self.result.metadata and self.result.metadata['rating'].get_string() != '': # Create hearts rating fullhearts = int(float(self.result.metadata['rating'].get_string())) * "\u2665" emptyhearts = (5 - int(float(self.result.metadata['rating'].get_string()))) * "\u2661" if self.result.metadata['rating'].get_string() != '0': preview.add_info(Unity.InfoHint.new("rating", _("Rating"), None, fullhearts+emptyhearts)) if "/patterns/" in self.result.icon_hint: wallpaper_action = Unity.PreviewAction.new("wallpaper", _("Set as wallpaper"), None) preview.add_action(wallpaper_action) icon = Gio.FileIcon.new (Gio.file_new_for_path(PROVIDER_ICON)) view_action = Unity.PreviewAction.new("view", _("View"), icon) preview.add_action(view_action) return preview class Scope (Unity.AbstractScope): def __init__(self): Unity.AbstractScope.__init__(self) def do_get_search_hint (self): return SEARCH_HINT def do_get_schema (self): ''' Adds specific metadata fields ''' schema = Unity.Schema.new () if EXTRA_METADATA: for m in EXTRA_METADATA: schema.add_field(m['id'], m['type'], m['field']) #FIXME should be REQUIRED for credits schema.add_field('provider_credits', 's', Unity.SchemaFieldType.OPTIONAL) return schema def do_get_categories (self): ''' Adds categories ''' cs = Unity.CategorySet.new () if CATEGORIES: for c in CATEGORIES: cat = Unity.Category.new (c['id'], c['name'], Gio.ThemedIcon.new(c['icon']), c['renderer']) cs.add (cat) return cs def do_get_filters (self): ''' Adds filters ''' fs = Unity.FilterSet.new () # if FILTERS: # return fs def do_get_group_name (self): return GROUP_NAME def do_get_unique_name (self): return UNIQUE_PATH def do_create_search_for_query (self, search_context): se = MySearch (search_context) return se def do_create_previewer(self, result, metadata): rp = Preview() rp.set_scope_result(result) rp.set_search_metadata(metadata) return rp def do_activate(self, result, metadata, id): if id == 'wallpaper': self.wallpaper_action(result.icon_hint) return Unity.ActivationResponse(handled=Unity.HandledType.SHOW_DASH, goto_uri=None) return Unity.ActivationResponse() def wallpaper_action(self, image): pattern_name = image.split('/')[-1] local_path = os.path.join(CACHE, pattern_name) if not os.path.isfile(local_path): if not os.path.isdir(CACHE): os.makedirs(CACHE) urllib.request.urlretrieve(image, local_path) self.set_as_wallpaper(local_path) return def set_as_wallpaper(self, pattern): gsettings = Gio.Settings.new('org.gnome.desktop.background') gsettings.set_string('picture-uri', "file://" + pattern) gsettings.set_string('picture-options', "wallpaper") gsettings.apply() def load_scope(): return Scope() unity-scope-colourlovers-0.1+13.10.20130723/src/__init__.py0000644000015700001700000000000012173420442023603 0ustar pbuserpbgroup00000000000000unity-scope-colourlovers-0.1+13.10.20130723/setup.py0000644000015700001700000000125612173420442022433 0ustar pbuserpbgroup00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- from distutils.core import setup from DistUtilsExtra.command import * setup(name='unity-scope-colourlovers', version='0.1', author='David Callé', author_email='davidc@framli.eu', url='http://launchpad.net/ubuntu-scopes', license='GNU General Public License (GPL)', data_files=[ ('share/dbus-1/services', ['data/unity-scope-colourlovers.service']), ('share/unity-scopes/colourlovers', ['src/unity_colourlovers_daemon.py']), ('share/unity-scopes/colourlovers', ['src/__init__.py']), ], cmdclass={'build': build_extra.build_extra, 'build_i18n': build_i18n.build_i18n,}) unity-scope-colourlovers-0.1+13.10.20130723/setup.cfg0000644000015700001700000000022112173420442022531 0ustar pbuserpbgroup00000000000000[build] i18n=True [build_i18n] domain=unity-scope-colourlovers desktop_files=[('share/unity/scopes/graphics', ('data/colourlovers.scope.in',))] unity-scope-colourlovers-0.1+13.10.20130723/data/0000755000015700001700000000000012173421326021630 5ustar pbuserpbgroup00000000000000unity-scope-colourlovers-0.1+13.10.20130723/data/unity-scope-colourlovers.service0000644000015700001700000000024712173420442030226 0ustar pbuserpbgroup00000000000000[D-BUS Service] Name=com.canonical.Unity.Scope.Graphics.Colourlovers Exec=/usr/bin/python3 /usr/share/unity-scopes/scope-runner-dbus.py -s graphics/colourlovers.scope unity-scope-colourlovers-0.1+13.10.20130723/data/colourlovers.scope.in0000644000015700001700000000163512173420442026031 0ustar pbuserpbgroup00000000000000[Scope] DBusName=com.canonical.Unity.Scope.Graphics.Colourlovers DBusPath=/com/canonical/unity/scope/graphics/colourlovers Icon=/usr/share/icons/unity-icon-theme/places/svg/service-colourlovers.svg _Keywords=colourlovers;color;colors;patterns;pattern;palette;palettes; RequiredMetadata= OptionalMetadata=description[s];comment_nb[s];date_created[s];rating[s]; Loader=/usr/share/unity-scopes/colourlovers/unity_colourlovers_daemon.py Module=colourlovers.unity_colourlovers_daemon ModuleType=python3 RemoteContent=true Type=graphics _Name=COLOURlovers _Description=This is an Ubuntu search plugin that enables information from COLOURlovers to be searched and displayed in the Dash underneath the Graphics header. If you do not wish to search this content source, you can disable this search plugin. _SearchHint=Search COLOURlovers palettes, patterns and colors [Desktop Entry] X-Ubuntu-Gettext-Domain=unity-scope-colourlovers unity-scope-colourlovers-0.1+13.10.20130723/data/icons/0000755000015700001700000000000012173421326022743 5ustar pbuserpbgroup00000000000000unity-scope-colourlovers-0.1+13.10.20130723/data/icons/service-colourlovers.svg0000644000015700001700000000751712173420442027670 0ustar pbuserpbgroup00000000000000 image/svg+xml