Peppermint OS Community Forum

General => General Discussion => Topic started by: mac on January 30, 2017, 08:15:59 am

Title: Vivaldi
Post by: mac on January 30, 2017, 08:15:59 am
Hi Folks,
You might want to take a look at Vivaldi browser vivaldi.com (http://vivaldi.com).  It was created by the developer of Opera (recently sold) and built on Chrome except it doesn't collect your information and call home.  I've been kicking the tires on it and bit and like it very well, thus far.  Tons of features. 

cheers
mac
 ;)
Title: Re: Vivaldi
Post by: emegra on January 30, 2017, 08:49:25 am
Hi mac

I tried Vivaldi a while ago and remember being impressed with it but I had some issues but for the life of me I can't remember what they were now but the project was in it's infancy at that time so these issues could well be sorted out now.

Another thing that put me off is that it's closed source if my memory serves me right



Graeme

Title: Re: Vivaldi
Post by: scifidude79 on January 30, 2017, 09:27:59 am
I may give it a whirl.  Never was much of an Opera fan, but I may like this.

Another thing that put me off is that it's closed source if my memory serves me right

Yeah, it has a proprietary license.
Title: Re: Vivaldi
Post by: mac on January 30, 2017, 09:34:45 am
source codes available HERE (https://vivaldi.com/source/)

Quote
The browser is actually based on the Chromium engine (Which is open source and licensed under BSD license). Meaning that the core of the browser (90% of it) is available to the public. Other components and modifications – such as the UI – are also “viewable” and can be downloaded from vivaldi.com/source.    [But] there’s no “complete license” for the whole project. It can’t be said the Vivaldi is actually open source and licensed under “BSD” license. Some files in the source code have their own copyright notice. Meaning that it’s not free (as in freedom). But it can be said that Vivaldi provides the major part of its code to the public “to view”.
....from an article HERE (https://fosspost.org/2017/01/28/vivaldi-new-modern-web-browser/)
Title: Re: Vivaldi
Post by: scifidude79 on January 30, 2017, 10:39:40 am
Basically, it's a lot like Chrome.  Open Source for the most part, but with a few proprietary touches.  Either way, it doesn't matter to me.  I'm fine with using proprietary software, I do it every time I boot my main desktop computer.  (graphics driver)
Title: Re: Vivaldi
Post by: mac on January 30, 2017, 10:40:52 am
I do have one complaint about it which is that it loads a bit slow.....something on the order of FF.   Runs fast enough once it is loaded, though.  If anyone would like I can give a couple of tweaks. 

cheers
Title: Re: Vivaldi
Post by: perknh on January 30, 2017, 12:21:31 pm
Hi mac,

Do you like Vivaldi better than Chromium?  I know Opera is, has been, and probably will be buggy --but it still honors Norway's privacy laws.  Would that mean it still calls home to China?  I really don't know.  And, Yandex, although it moves like lightning, it now has to deal with new Russian data policies --which aren't in the average user's interest, I might add.  Vivaldi has an active forum, but I noticed that one the flaming creeps that was in Opera's forum from years ago has now migrated to the Vivaldi forum.  He and another clown were two of the reasons why I moved to the now defunct Maxthon for LInux years ago.  I haven't yet found how to install Vivaldi from the command line as I have with Opera and Yandex either.  But, overall, after weeding out all the sites it adds by default, would you still give Vivaldi a thumbs up?  I suspect you feel better with Vivaldi than Chrome, but Chromium ?

By the way, I always felt that Chrome was excellent on matters of security, but lousy on matters of privacy.  I think Google/Alphabet wants to track us for ad revenue. 

perknh
Title: Re: Vivaldi
Post by: mac on January 30, 2017, 12:43:40 pm
I always felt that Chrome was excellent on matters of security, but lousy on matters of privacy.  I think Google/Alphabet wants to track us for ad revenue

Agreed.   As I understand it, Chrome is the most secure browser but collects & keeps user data something awful.   I like browsers built on Chrome but without the data mining.
I'm still experimenting with Vivaldi and the verdict is not in, yet, for me.   I like the quickness of Opera (but it's buyer is a bit unsettling.....especially considering its less-than-friendly relationship with the US) and the privacy of FF and generally use one of those two with the advantage going to Opera (at least for me but, of course, YMMV).   Vivaldi is supposed to offer security and privacy but is slower than Opera but about the same as FF (maybe a little slower).   I'm still playing around with it and tweaking here and there.  We'll see.  But, for now, yes I do like it.....the note feature is a great tool IMHO. 

Yandex is a good browser but I share your concerns.  SlimJet is another one I've tried but found a bit flaky as with Maxthon but both are very much usable.  At any rate, I'll keep you posted.

cheers perk,
mac

Title: Re: Vivaldi
Post by: PCNetSpec on January 30, 2017, 05:29:35 pm
I have a version of ICE that supports Vivaldi (and still FF, Chromium, Chrome) if you're interested mac ?
Title: Re: Vivaldi
Post by: mac on January 30, 2017, 05:33:08 pm
Absolutely!  Thanks.....
Title: Re: Vivaldi
Post by: AndyInMokum on January 30, 2017, 05:47:22 pm
Hi mac, I followed the instructions here: ICE Vivaldi (https://forum.peppermintos.com/index.php/topic,4768.msg47659.html#msg47659)  ;).
Title: Re: Vivaldi
Post by: mac on January 30, 2017, 05:52:42 pm
Hey Andy, thanks.  I'll give it a shot  :)

cheers
Title: Re: Vivaldi
Post by: PCNetSpec on January 30, 2017, 06:00:12 pm
NO .. don't do that, those instructions SWAP Chrome support to Vivaldi (You loose Chrome support) .. I have one that ADDS Vivaldi support.

I'll post it in a bit.
Title: Re: Vivaldi
Post by: mac on January 30, 2017, 06:02:06 pm
Okay.  Take you time, mate, I know you're a busy man.   ;)  No hurry.
Title: Re: Vivaldi
Post by: PCNetSpec on January 30, 2017, 06:06:37 pm
First backup ice:
Code: [Select]
sudo cp -v /usr/bin/ice /usr/bin/ice.bak
now open ice for editing:
Code: [Select]
sudo pluma /usr/bin/ice
and make it read
Code: [Select]
#!/usr/bin/env python3
#
# by Kendall Weaver <kendall@peppermintos.com>
# for Peppermint OS
# modified by Mark Greaves (PCNetSpec) <mark@peppermintos.com>
#
# Ice is a simple Site Specific Browser (SSB) manager for Chromium and
# Chrome specifically intended to integrate with the LXDE menu system.
# Unlike the built-in functions in the browsers, Ice boasts the ability
# to remove SSBs, validate addresses, and prevent overwriting existing
# SSBs. Special thanks to Matt Phillips <labratmatt@gmail.com> for the
# excellent pyfav library that is integrated into this application.
# ADDENDUM: Added support for Firefox (via "ice-firefox") and Vivaldi.

import os
import sys
import requests
import urllib.request
import urllib.parse
import urllib.error
import os.path
import string
import gi  ## added by MG ##
gi.require_version('Gtk','3.0') ## added by MG ##
from gi.repository import Gtk
from gi.repository.GdkPixbuf import Pixbuf
from urllib.parse import urlparse, urlunparse
from bs4 import BeautifulSoup


_HOME = os.getenv("HOME")
_ICE_DIR = "{0}/.local/share/ice".format(_HOME)
_APPS_DIR = "{0}/.local/share/applications".format(_HOME)
_ICE_ICON = "/usr/share/pixmaps/ice.png"
_CHROME_BIN = "/usr/bin/google-chrome"
_CHROMIUM_BIN = "/usr/bin/chromium-browser"
_VIVALDI_BIN = "/usr/bin/vivaldi"
_FIREFOX_BIN = "/usr/bin/firefox"


# Requisite dirs
if not os.path.exists(_ICE_DIR):
    os.system("mkdir -p {0}".format(_ICE_DIR))

if not os.path.exists(_APPS_DIR):
    os.system("mkdir -p {0}".format(_APPS_DIR))

headers = {
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) \
        AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.152 \
        Safari/537.36'
}


def get_details(app):
    a = open(app, 'r')
    nameline = ""
    iconline = ""
    is_ice = False

    for line in a:
        if "Name=" in line:
            array = line.replace("=", " ").split()
            array.pop(0)
            for word in array:
                nameline = nameline + word + " "
        elif "Icon=" in line:
            array = line.replace("=", " ").split()
            array.pop(0)
            for word in array:
                iconline = iconline + word
            try:
                pixbuf = Pixbuf.new_from_file_at_size(iconline, 16, 16)
            except:
                pixbuf = Pixbuf.new_from_file_at_size(_ICE_ICON, 16, 16)
        elif "StartupWMClass=Chromium" in line:
            is_ice = True

    if nameline is not None and iconline is not None and is_ice is True:
        return (nameline, pixbuf)

    return (None, None)


def normalize(url):
    (scheme, netloc, path, _, _, frag) = urlparse(url, "http")
    if not netloc and path:
        return urlunparse((scheme, path, "", "", "", ""))

    return urlunparse((scheme, netloc, path, "", "", ""))


def errortest(url):
    try:
        urllib.request.urlopen(url)
        return True
    except (urllib.request.HTTPError, urllib.request.URLError):
        return False


def download_favicon(url, file_prefix='', target_dir='/tmp'):
    parsed_site_uri = urlparse(url)

    if not parsed_site_uri.scheme:
        url = 'http://{0}'.format(url)
        parsed_site_uri = urlparse(url)

    if not parsed_site_uri.scheme or not parsed_site_uri.netloc:
        raise Exception("Unable to parse URL, {0}".format(url))

    favicon_url = get_favicon_url(url)

    if not favicon_url:
        raise Exception("Unable to find favicon for, {0}".format(url))

    response = requests.get(favicon_url, headers=headers)
    if response.status_code == requests.codes.ok:
        parsed_uri = urlparse(favicon_url)
        favicon_filepath = parsed_uri.path
        favicon_path, favicon_filename = os.path.split(favicon_filepath)

    valid_chars = "-_.() %s%s" % (string.ascii_letters, string.digits)

    sanitized_filename = "".join([x if valid_chars else "" for x in favicon_filename])

    sanitized_filename = os.path.join(target_dir, file_prefix + sanitized_filename)

    with open(sanitized_filename, 'wb') as f:
            for chunk in response.iter_content(chunk_size=1024):
                if chunk:  # filter out keep-alive new chunks
                    f.write(chunk)
                    f.flush()

    return sanitized_filename


def parse_markup_for_favicon(markup, url):
    parsed_site_uri = urlparse(url)

#    soup = BeautifulSoup(markup)
    soup = BeautifulSoup(markup, "lxml") ## edited by MG ##

    icon_link = soup.find('link', rel='icon')
    if icon_link and icon_link.has_attr('href'):

        favicon_url = icon_link['href']

        if favicon_url.startswith('//'):
            parsed_uri = urlparse(url)
            favicon_url = "{0}:{1}".format(parsed_uri.scheme, favicon_url)

        elif favicon_url.startswith('/'):
            favicon_url = "{0}://{1}{2}".format(parsed_site_uri.scheme, parsed_site_uri.netloc, favicon_url)

        elif not favicon_url.startswith('http'):
            path, filename = os.path.split(parsed_site_uri.path)
            favicon_url = "{0}://{1}/{2}".format(parsed_site_uri.scheme, parsed_site_uri.netloc,
                                                 os.path.join(path, favicon_url))

        return favicon_url

    return None


def get_favicon_url(url):
    parsed_site_uri = urlparse(url)

    try:
        response = requests.get(url, headers=headers)
    except:
        raise Exception("Unable to find URL. Is it valid? {0}".format(url))

    if response.status_code == requests.codes.ok:
        favicon_url = parse_markup_for_favicon(response.content, url)

        if favicon_url:
            return favicon_url

    favicon_url = '{uri.scheme}://{uri.netloc}/favicon.ico'.format(uri=parsed_site_uri)

    response = requests.get(favicon_url, headers=headers)
    if response.status_code == requests.codes.ok:
        return favicon_url

    return None


def applicate():
    title = name.get_text()
    address = normalize(url.get_text())

    semiformatted = ""
    array = filter(str.isalpha, title)
    for obj in array:
        semiformatted = semiformatted + obj
    formatted = semiformatted.lower()

    loc = where.get_active_text()
    if loc == "Accessories":
        location = "Utility;"
    elif loc == "Games":
        location = "Game;"
    elif loc == "Graphics":
        location = "Graphics;"
    elif loc == "Internet":
        location = "Network;"
    elif loc == "Office":
        location = "Office;"
    elif loc == "Programming":
        location = "Development;"
    elif loc == "Sound & Video":
        location = "AudioVideo;"
    elif loc == "System Tools":
        location = "System;"

    global iconpath
    iconname = iconpath.replace("/", " ").split()[-1]
    iconext = iconname.replace(".", " ").split()[-1]

    if os.path.exists("{0}/{1}.desktop".format(_APPS_DIR, formatted)):
        DuplicateError(title, formatted, address, iconext, location)
    else:
        writefile(title, formatted, address, iconext, location)


def writefile(title, formatted, address, iconext, location):
    global iconpath
    os.system("cp --force {0} {1}/{2}.{3}".format(iconpath, _ICE_DIR, formatted, iconext))
    appfile = os.path.expanduser("{0}/{1}.desktop".format(_APPS_DIR, formatted))
    os.system("touch {0}".format(appfile))
    if chrome.get_active() == True:
        browser = "google-chrome"
    elif chromium.get_active() == True:
        browser = "chromium-browser"
    elif vivaldi.get_active() == True:
        browser = "vivaldi"
    elif firefox.get_active() == True:
        browser = "ice-firefox"
    else:
        print("ERROR: An unknown browser selection error has occurred.")
        sys.exit(1)

    with open(appfile, 'w') as appfile1:
        appfile1.truncate()
        appfile1.write("[Desktop Entry]\n")
        appfile1.write("Version=1.0\n")
        appfile1.write("Name={0}\n".format(title))
        appfile1.write("Comment={0} (Ice SSB)\n".format(title))

        if (browser == "ice-firefox"):
            appfile1.write("Exec={0} {1}\n".format(browser, address))
        else:
            appfile1.write("Exec={0} --app={1}\n".format(browser, address))

        appfile1.write("Terminal=false\n")
        appfile1.write("X-MultipleArgs=false\n")
        appfile1.write("Type=Application\n")
        appfile1.write("Icon={0}/.local/share/ice/{1}.{2}\n".format(_HOME, formatted, iconext))
        appfile1.write("Categories=GTK;{0}\n".format(location))
        appfile1.write("MimeType=text/html;text/xml;application/xhtml_xml;\n")
        appfile1.write("StartupWMClass=Chromium\n")
        appfile1.write("StartupNotify=true\n")

        if (browser == "ice-firefox"):
            address1 = str.replace(address, 'http://', '')
            address2 = str.replace(address1, 'https://', '')
            address3 = str.replace(address2, '/', '_')
            appfile1.write("IceFirefox={0}".format(address3))

    name.set_text("")
    url.set_text("")
    iconpath = _ICE_ICON
    new_icon = Pixbuf.new_from_file_at_size(iconpath, 32, 32)
    icon.set_from_pixbuf(new_icon)
    iconline, pixbuf = get_details(appfile)
    liststore.prepend([pixbuf, iconline])


def delete(button):
    a = iconview.get_selected_items()
    b = liststore.get_iter(a[0])
    c = liststore.get_value(b, 1)
    liststore.remove(b)

    semiformatted = ""
    array = filter(str.isalpha, c)

    for obj in array:
        semiformatted = semiformatted + obj

    formatted = semiformatted.lower()
    appfile = "{0}/{1}.desktop".format(_APPS_DIR, formatted)

    appfileopen = open(appfile, 'r')
    appfilelines = appfileopen.readlines()
    appfileopen.close()

    for line in appfilelines:
        if "IceFirefox=" in line:
            profile = str.replace(line, 'IceFirefox=', '')
            directory = os.path.expanduser('{0}/firefox'.format(_ICE_DIR))

            for profiles in os.listdir(directory):
                if profile in profiles:
                    os.system("rm -rf {0}/{1}".format(directory, profile))

    os.system("rm {0}".format(appfile))


class IconSel(Gtk.FileChooserDialog):

    def __init__(self):

        def update_image(dialog):
            filename = dialog.get_preview_filename()

            try:
                pixbuf = Pixbuf.new_from_file(filename)
                preview.set_from_pixbuf(pixbuf)
                valid_preview = True
            except:
                valid_preview = False

            dialog.set_preview_widget_active(valid_preview)

        filew = Gtk.FileChooserDialog(
            "Please choose an icon.",
            None,
            Gtk.FileChooserAction.OPEN,
            (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
        filew.set_filename(_ICE_ICON)

        filter1 = Gtk.FileFilter()
        filter1.set_name("Icons")
        filter1.add_mime_type("image/png")
        filter1.add_mime_type("image/jpeg")
        filter1.add_mime_type("image/gif")
        filter1.add_pattern("*.png")
        filter1.add_pattern("*.jpg")
        filter1.add_pattern("*.gif")
        filter1.add_pattern("*.xpm")
        filter1.add_pattern("*.svg")
        filew.add_filter(filter1)

        preview = Gtk.Image()
        filew.set_preview_widget(preview)
        filew.connect("update-preview", update_image)

        response = filew.run()
        if response == Gtk.ResponseType.OK:
            global iconpath
            iconpath = filew.get_filename()
            new_icon = Pixbuf.new_from_file_at_size(iconpath, 32, 32)
            icon.set_from_pixbuf(new_icon)
            filew.destroy()
        elif response == Gtk.ResponseType.CANCEL:
            filew.destroy()


class NoBrowserError(Gtk.Window):

    def destroy(self, button):
        self.close()

    def __init__(self):
        Gtk.Window.__init__(self, title="Browser Error")
        self.set_size_request(250, 130)
        self.set_icon_from_file(_ICE_ICON)

        print("test")

        main_lab = Gtk.Label()
        main_lab.set_markup("<b>Warning: No Suitable Browser Detected</b>")
        text_lab = Gtk.Label("The name of the SSB will cause an existing SSB to\nbe overwritten. To prevent this, change a letter in\nthe name. Continue anyway?")
        text_lab = Gtk.Label("Ice requires a system installation of either Google\nChrome or Chromium in order to function. Please\ninstall at least one in order to create SSBs.")

        close = Gtk.Button.new_from_stock(Gtk.STOCK_CLOSE)
        close.connect("clicked", self.destroy)
        void = Gtk.Label()
        box = Gtk.HBox()
        box.pack_start(void, True, True, 0)
        box.pack_start(close, False, False, 0)

        main_vbox = Gtk.VBox()
        main_vbox.pack_start(main_lab, False, False, 10)
        main_vbox.pack_start(text_lab, False, False, 0)
        main_vbox.pack_start(box, False, False, 10)

        main_hbox = Gtk.HBox()
        main_hbox.pack_start(main_vbox, True, True, 10)
        self.add(main_hbox)
        self.show_all()


class DuplicateError(Gtk.Window):

    def destroy(self, button):
        self.close()

    def okay_clicked(self, button, title, formatted, address, iconext, location):

        for item in liststore:
            itemiter = item.iter
            semiformatted = ""
            array = filter(str.isalpha, item[1])

            for obj in array:
                semiformatted = semiformatted + obj

            forma = semiformatted.lower()

            if forma == formatted:
                liststore.remove(itemiter)

        writefile(title, formatted, address, iconext, location)
        self.close()

    def __init__(self, title, formatted, address, iconext, location):
        Gtk.Window.__init__(self, title="Duplication Error")
        self.set_size_request(250, 130)
        self.set_icon_from_file(_ICE_ICON)

        main_lab = Gtk.Label()
        main_lab.set_markup("<b>Warning: File Duplication Error</b>")
        text_lab = Gtk.Label("The name of the SSB will cause an existing SSB to\nbe overwritten. To prevent this, change a letter in\nthe name. Continue anyway?")

        okay = Gtk.Button.new_from_stock(Gtk.STOCK_OK)
        okay.connect("clicked", self.okay_clicked, title, formatted, address, iconext, location)
        cancel = Gtk.Button.new_from_stock(Gtk.STOCK_CANCEL)
        cancel.connect("clicked", self.destroy)
        void = Gtk.Label()
        box = Gtk.HBox()
        box.pack_start(void, True, True, 0)
        box.pack_start(okay, False, False, 10)
        box.pack_start(cancel, False, False, 0)

        main_vbox = Gtk.VBox()
        main_vbox.pack_start(main_lab, False, False, 10)
        main_vbox.pack_start(text_lab, False, False, 0)
        main_vbox.pack_start(box, False, False, 10)

        main_hbox = Gtk.HBox()
        main_hbox.pack_start(main_vbox, True, True, 10)
        self.add(main_hbox)
        self.show_all()


class AddressError(Gtk.Window):

    def destroy(self, button):
        self.close()

    def okay_clicked(self, button):
        applicate()
        self.close()

    def __init__(self):
        Gtk.Window.__init__(self, title="Address Error")
        self.set_size_request(250, 130)
        self.set_icon_from_file(_ICE_ICON)

        main_lab = Gtk.Label()
        main_lab.set_markup("<b>Warning: HTTP or URL Error</b>")
        text_lab = Gtk.Label("An error with the web address has been detected.\nThis is possibly the site being down or unavailable\nright now. Continue anyway?")

        okay = Gtk.Button.new_from_stock(Gtk.STOCK_OK)
        okay.connect("clicked", self.okay_clicked)
        cancel = Gtk.Button.new_from_stock(Gtk.STOCK_CANCEL)
        cancel.connect("clicked", self.destroy)
        void = Gtk.Label()
        box = Gtk.HBox()
        box.pack_start(void, True, True, 0)
        box.pack_start(okay, False, False, 10)
        box.pack_start(cancel, False, False, 0)

        main_vbox = Gtk.VBox()
        main_vbox.pack_start(main_lab, False, False, 10)
        main_vbox.pack_start(text_lab, False, False, 0)
        main_vbox.pack_start(box, False, False, 10)

        main_hbox = Gtk.HBox()
        main_hbox.pack_start(main_vbox, True, True, 10)
        self.add(main_hbox)
        self.show_all()


class Ice(Gtk.Window):

    def destroy(self, button):
        Gtk.main_quit()

    def icon_select(self, button):
        IconSel()

    def apply_clicked(self, button):
        if errortest(normalize(url.get_text())) is True:
            applicate()
        elif errortest(normalize(url.get_text())) is False:
            AddressError()
        elif errortest(normalize(url.get_text())) is None:
            print("ERROR: An address error has occurred.")
            sys.exit(1)
        else:
            print("ERROR: An unknown error has occurred.")
            sys.exit(1)

    def icon_download(self, button):
        appurl = normalize(url.get_text())
        global iconpath
        try:
            download_favicon(appurl)
            addr0 = get_favicon_url(appurl)
            addr1 = addr0.replace('/', ' ')
            addr2 = addr1.split()[-1]
            iconpath = "/tmp/{0}".format(addr2)
            new_icon = Pixbuf.new_from_file_at_size(iconpath, 32, 32)
            icon.set_from_pixbuf(new_icon)
        except:
            iconpath = _ICE_ICON
            new_icon = Pixbuf.new_from_file_at_size(iconpath, 32, 32)
            icon.set_from_pixbuf(new_icon)

    def __init__(self):
        Gtk.Window.__init__(self, title="Ice")
        self.current_directory = os.path.realpath(_APPS_DIR)
        self.set_size_request(460, 350)
        self.set_icon_from_file(_ICE_ICON)

        ######################
        #   'Create' page.   #
        ######################

        welcome = Gtk.Label()
        welcome.set_markup("<b>Welcome to Ice, a simple SSB manager.</b>")
        global name
        name = Gtk.Entry()
        name.set_placeholder_text("Name the application")
        global url
        url = Gtk.Entry()
        url.set_placeholder_text("Enter web address")

        where_store = ["Accessories", "Games", "Graphics", "Internet",
                       "Office", "Programming", "Sound & Video", "System Tools"]
        where_lab = Gtk.Label("Where in the menu?")
        global where
        where = Gtk.ComboBoxText()
        where.set_entry_text_column(0)
        for entry in where_store:
            where.append_text(entry)
        where.set_active(3)

        where_box = Gtk.HBox()
        where_void = Gtk.Label()
        where_box.pack_start(where_lab, False, False, 0)
        where_box.pack_start(where_void, False, False, 10)
        where_box.pack_start(where, True, True, 0)

        global iconpath
        iconpath = _ICE_ICON
        icon_pixbuf = Pixbuf.new_from_file_at_size(iconpath, 32, 32)
        global icon
        icon = Gtk.Image()
        icon.set_from_pixbuf(icon_pixbuf)

        icon_void = Gtk.Label()
        icon_box = Gtk.HBox()
        icon_box.pack_start(icon, False, False, 10)
        icon_box.pack_start(icon_void, False, False, 10)

        choose_icon = Gtk.Button("Select an icon")
        choose_icon.connect("clicked", self.icon_select)
        download_icon = Gtk.Button("Use site favicon")
        download_icon.connect("clicked", self.icon_download)

        icon_vbox = Gtk.VBox()
        icon_vbox.pack_start(choose_icon, True, True, 5)
        icon_vbox.pack_start(download_icon, True, True, 5)
        icon_hbox = Gtk.HBox()
        icon_hbox.pack_start(icon_box, False, False, 10)
        icon_hbox.pack_start(icon_vbox, True, True, 0)

        global firefox
        firefox = Gtk.RadioButton.new_with_label_from_widget(None, "Firefox")

        if not os.path.exists(_FIREFOX_BIN):
            firefox.set_sensitive(False)

        if not os.path.exists(_CHROMIUM_BIN) and not \
                os.path.exists(_CHROME_BIN) and not \
                os.path.exists(_VIVALDI_BIN) and \
                os.path.exists(_FIREFOX_BIN):
            firefox.set_active(True)

        global chrome
        chrome = Gtk.RadioButton.new_from_widget(firefox)
        chrome.set_label("Chrome")

        if not os.path.exists(_CHROME_BIN):
            chrome.set_sensitive(False)

        if not os.path.exists(_CHROMIUM_BIN) and not \
                os.path.exists(_FIREFOX_BIN) and not \
                os.path.exists(_VIVALDI_BIN) and \
                os.path.exists(_CHROME_BIN):
            chrome.set_active(True)

        global vivaldi
        vivaldi = Gtk.RadioButton.new_from_widget(chrome)
        vivaldi.set_label("Vivaldi")

        if not os.path.exists(_VIVALDI_BIN):
            vivaldi.set_sensitive(False)

        if not os.path.exists(_CHROMIUM_BIN) and not \
                os.path.exists(_FIREFOX_BIN) and not \
                os.path.exists(_CHROME_BIN) and \
                os.path.exists(_VIVALDI_BIN):
            vivaldi.set_active(True)

        global chromium
        chromium = Gtk.RadioButton.new_from_widget(chrome)
        chromium.set_label("Chromium")

        if not os.path.exists(_CHROMIUM_BIN):
            chromium.set_sensitive(False)

        if not os.path.exists(_CHROME_BIN) and not \
                os.path.exists(_FIREFOX_BIN) and not \
                os.path.exists(_VIVALDI_BIN) and \
                os.path.exists(_CHROMIUM_BIN):
            chromium.set_active(True)

        apply_button = Gtk.Button.new_from_stock(Gtk.STOCK_APPLY)
        apply_button.connect("clicked", self.apply_clicked)
        close_button = Gtk.Button.new_from_stock(Gtk.STOCK_CLOSE)
        close_button.connect("clicked", self.destroy)
        button_void = Gtk.Label()
        button_box = Gtk.HBox()
        button_box.pack_start(chrome, False, False, 10)
        button_box.pack_start(chromium, False, False, 0)
        button_box.pack_start(vivaldi, False, False, 10)
        button_box.pack_start(firefox, False, False, 0)
        button_box.pack_start(button_void, True, True, 0)
        button_box.pack_start(close_button, False, False, 20)
        button_box.pack_start(apply_button, False, False, 0)

        create_vbox = Gtk.VBox()
        create_vbox.pack_start(welcome, False, False, 15)
        create_vbox.pack_start(name, False, False, 0)
        create_vbox.pack_start(url, False, False, 10)
        create_vbox.pack_start(where_box, False, False, 10)
        create_vbox.pack_start(icon_hbox, False, False, 10)
        create_vbox.pack_start(button_box, False, False, 0)

        create_hbox = Gtk.HBox()
        create_hbox.pack_start(create_vbox, True, True, 20)
        create_lab = Gtk.Label("Create")

        ######################
        #   'Remove' page.   #
        ######################

        global liststore
        liststore = Gtk.ListStore(Pixbuf, str)

        for fl in os.listdir(_APPS_DIR):
            a = "{0}/{1}".format(_APPS_DIR, fl)
            if not os.path.isdir(a):
                nameline, pixbuf = get_details(a)
                if nameline is not None and pixbuf is not None:
                    liststore.append([pixbuf, nameline])

        global iconview
        iconview = Gtk.IconView()
        iconview.set_model(liststore)
        iconview.set_pixbuf_column(0)
        iconview.set_text_column(1)
        iconview.set_selection_mode(1)

        scroll = Gtk.ScrolledWindow()
        scroll.add(iconview)

        remove = Gtk.Button.new_from_stock(Gtk.STOCK_REMOVE)
        remove.connect("clicked", delete)
        close = Gtk.Button.new_from_stock(Gtk.STOCK_CLOSE)
        close.connect("clicked", self.destroy)
        void = Gtk.Label()
        buttons = Gtk.HBox()
        buttons.pack_start(void, True, True, 0)
        buttons.pack_start(close, False, False, 20)
        buttons.pack_start(remove, False, False, 0)

        remove_vbox = Gtk.VBox()
        remove_vbox.pack_start(scroll, True, True, 10)
        remove_vbox.pack_start(buttons, False, False, 0)

        remove_hbox = Gtk.HBox()
        remove_hbox.pack_start(remove_vbox, True, True, 20)
        remove_lab = Gtk.Label("Remove")

        ##########################
        #   Main window stuff.   #
        ##########################

        notebook = Gtk.Notebook()
        notebook.append_page(create_hbox, create_lab)
        notebook.append_page(remove_hbox, remove_lab)

        main_vbox = Gtk.VBox()
        main_vbox.pack_start(notebook, True, True, 10)
        main_hbox = Gtk.HBox()
        main_hbox.pack_start(main_vbox, True, True, 10)
        self.add(main_hbox)
        self.show_all()

        if not os.path.exists(_CHROME_BIN) and not \
                os.path.exists(_CHROMIUM_BIN) and not \
                os.path.exists(_VIVALDI_BIN) and not \
                os.path.exists(_FIREFOX_BIN):
            apply_button.set_sensitive(False)
            NoBrowserError()


if __name__ == '__main__':
    window = Ice()
    window.connect("delete-event", Gtk.main_quit)
    Gtk.main()
(be sure to get ALL of that)

SAVE the file.

Now run ICE .. you should see the Vivaldi tickbox at the bottom.
Title: Re: Vivaldi
Post by: AndyInMokum on January 30, 2017, 06:12:24 pm
NO .. don't do that, those instructions SWAP Chrome support to Vivaldi (You loose Chrome support) .. I have one that ADDS Vivaldi support.

I'll post it in a bit.

You added an edit at the bottom of the post that just added Vivaldi to the list of browsers, not replacing Chrome - works a treat too :).
Title: Re: Vivaldi
Post by: mac on January 30, 2017, 06:19:00 pm
Holy Moly Batman!  There's a box of Capt'N Crunch in your future.....keep a check down at the collection.  Ha!   :D
Title: Re: Vivaldi
Post by: PCNetSpec on January 30, 2017, 06:28:27 pm
NO .. don't do that, those instructions SWAP Chrome support to Vivaldi (You loose Chrome support) .. I have one that ADDS Vivaldi support.

I'll post it in a bit.

You added an edit at the bottom of the post that just added Vivaldi to the list of browsers, not replacing Chrome - works a treat too :).

Oops .. so I did :-[

Thanks Andy.



Quote from: mac
Holy Moly Batman!  There's a box of Capt'N Crunch in your future.....keep a check down at the collection.  Ha!   :D

Might just hold you to that Robin :)
Title: Re: Vivaldi
Post by: VinDSL on January 30, 2017, 06:39:01 pm
I have a version of ICE that supports Vivaldi (and still FF, Chromium, Chrome) if you're interested mac ?

Got one for Brave yet ?  I need the space ...


(http://vindsl.com/images/VinDSL-30-Jan-17-16:32:47.png)


j/k  -  All I use Brave for is printing coupons.  Don't ask me why.  I dunno.   :-\

Title: Re: Vivaldi
Post by: PCNetSpec on January 30, 2017, 08:42:35 pm
Good, because brave doesn't honour the "--app" option .. and I can't be bothered to write a whole new script messin with it's configs like we had to do for FF :D
Title: Re: Vivaldi
Post by: VinDSL on January 30, 2017, 10:30:45 pm
Just as well.  Brave freaks me out, at some level.

It's too pretty, or something.

Can't put a finger on it ...
Title: Re: Vivaldi
Post by: perknh on January 31, 2017, 07:22:33 am
Hi VinDSL,

You have to be brave to use Brave.  Brave browser lasted on my computer about 10 minutes.  I couldn't do anything with it.  The browser for us to keep our eyes on is Epic browser (https://www.epicbrowser.com/), but right now it does not support Linux.  There's still Iridium browser (https://iridiumbrowser.de/).  They're decent enough to warn us about the lag time between a Chromium to Iridium release.

Quote
Our ambition is to get builds for Debian, Ubuntu, openSUSE, fedora, Windows and OS-X a couple of days after a new release of Chromium.
To achieve this, we need help from individuals and organisations, who have the same intention. Currently there are weeks between a new release of Iridium and Chromium.
Please take this into consideration for your personal usage of the browser as you might be at risk when surfing unknown and potentially dangerous websites!
We feel, that as an application browser or as browser for trusted websites, this is acceptable.

Sometimes I wonder if the extensions we use are all they're cracked up to be. (Epic browser is not a big fan of extensions.)  A lot of these privacy oriented extensions can "read and change all the data on the websites you visit (http://www.howtogeek.com/188346/why-browser-extensions-can-be-dangerous-and-how-to-protect-yourself/)" (which is the same definition as spyware) the way that the browser did before.  Seems to me we're just just handing our data over from one company to another.  At the end of the day we have to trust that these companies that focus on extensions are genuinely working in our best interest.

This (http://www.howtogeek.com/100361/how-to-optimize-google-chrome-for-maximum-privacy/) is a dated article about Chrome and our privacy, but the info contained within it is still valid, I believe.  Even though I only use one computer, I use the sync feature in Chromium and Chrome.  I really should be encrypting all my data across Google's servers (https://support.google.com/chrome/answer/1181035?visit_id=1-636214584210335089-2008230196&p=settings_encryption&rd=1) but it's just a pain in the neck so I don't do it.  The other things we could do is to not save bookmarks, not use Gmail, etc. 

I get one medically related email from the UK each month.  I learn more from that email than from anything here in the States.  Well, it doesn't take a rocket scientist to figure out that I, or perhaps a family member, has a medical condition.  Now, Google has that info.  Now if Uncle Sam has that info too, he sure hasn't shown me that he cares about it.  So there probably a profile on each of us somewhere.  But there's just too much data out there for it to be very important.  As an example I"ll guess that PCNetSpec, AndyInMokum, and murraymint probably drink tea --maybe throughout the day.  And they can probably guess that you, mac, rjm65, and I start our days with some coffee.  (Other than myself, I have no idea if any of this is really so.) Yeah, this data would be interesting, but does it matter?  I don't know.  I think we're swamped in data that doesn't really mean a whole heck of a lot.  I know it's a human right to have privacy, and I want more of it and not less, but a lot of this data is just plain useless for anything other than advertisements and sales.  I mention Yandex, I'll be looking at Russian dating services tomorrow in Peppermint.  I mention mac and I get offers for McDonald's coupons.  I mention tea, and I hope to see a reasonable offer on some Earl Grey tea soon --Twinings I might add!

I mentioned the price of printer ink recently in our forum and I got an advertisement from inkfarm.com the other day.  But, I'd still look on Amazon too, and emegra has suggested --and maybe even Ebay!  ;)
Title: Re: Vivaldi
Post by: PCNetSpec on January 31, 2017, 08:38:21 am
It might be interesting to do a comparison....

As a Firefox user I can't say that I've noticed simply posting content on say this forum changes my adverts (maybe a Chromium based browser thing ?) .. Google searches (and if I actually click an advert out of curiosity) is a completely different matter though .. I VERY quickly learned NOT to be curious and click an advert, as similar adverts then follow you for AGES ::)
Title: Re: Vivaldi
Post by: mac on January 31, 2017, 10:30:35 am
I think we're swamped in data that doesn't really mean a whole heck of a lot
True 'dat, Perk.    ;)

cheers
Title: Re: Vivaldi
Post by: mac on January 31, 2017, 10:36:12 am
It might be interesting to do a comparison....

As a Firefox user I can't say that I've noticed simply posting content on say this forum changes my adverts (maybe a Chromium based browser thing ?) .. Google searches (and if I actually click an advert out of curiosity) is a completely different matter though .. I VERY quickly learned NOT to be curious and click an advert, as similar adverts then follow you for AGES ::)
I have noticed that watching anything on YouTube brings an onslaught of ads about whatever "they" think is related.   The same thing, of course, with searches.  You can bet you're always being "watched."   They know what you did last summer.  Ha!
Title: Re: Vivaldi
Post by: perknh on January 31, 2017, 12:42:15 pm
I just encrypted all our data in Google with my sync password.  The message reads:

Quote
All data was encrypted with my sync password on January 31, 2017

It was quite simple to do.  I'm also down to one extension now --LastPass.  Blocking third-party cookies, encrypting our data, sending a "Do Not Track" request (which may or not be honored), using Safe Browsing Protection (https://www.google.com/intl/en/chrome/browser/privacy/whitepaper.html#malware), not allowing sites to track our physical location, not allowing sites to use a plugin to access our computer, turning off MIDI devices to control aspects of our computer, using Chromium browser along with using Cisco's FamilySafe DNS and DNSCrypt behind a NAT and a software firewall, ought to be protection enough for any ordinary Joe and Jane using Peppermint. 

Phew!  ::)

Thanks, mac, for this thread.  It sure got me thinking this morning.  :)

perknh
Title: Re: Vivaldi
Post by: mac on January 31, 2017, 12:53:53 pm
Thanks, mac, for this thread.  It sure got me thinking this morning.  :)
perknh
Oh my!  Sorry to hear that, Perk.  If you're like me that hurts   :D

cheers
Title: Re: Vivaldi
Post by: perknh on January 31, 2017, 04:19:03 pm
Oh my!  Sorry to hear that, Perk.  If you're like me that hurts   :D

I am!  Both the brain AND the body hurt in the morning.  ;)
Title: Re: Vivaldi
Post by: PCNetSpec on February 11, 2017, 10:12:09 am
Vivaldi support has now been added to ICE via an update .. as long as you have ICE version 5.2.4 you should be able to select Vivaldi as the backend for newly created SSB's (as log as you have Vivaldi installed, or the option will be greyed).
Title: Re: Vivaldi
Post by: kimbopeppermint on March 05, 2017, 10:31:08 pm
I found it to be a little too welcoming to JavaScript and lacking the features of Chromium such as built in script blocking and whitelisting.
Title: Re: Vivaldi
Post by: perknh on March 13, 2018, 08:11:18 pm
You have to be brave to use Brave.  Brave browser lasted on my computer about 10 minutes.  I couldn't do anything with it.

I know this is an old thread about Vivaldi, but I take back what I said earlier about Brave browser.  Brave browser is free and open source, focused on privacy, and it's easy to configure.  It's also working fine for me now in Peppermint 8.  Brave is an impressive browser.
Title: Re: Vivaldi
Post by: PCNetSpec on March 13, 2018, 10:29:33 pm
Won't work with ICE though .. and can't (as far as I can tell) be made to :(