Exemple #1
0
"""Functions related to setting the wallpaper."""

from pathlib import Path
from os import makedirs, remove

from downloader_cli.download import Download
from simber import Logger
from QuickWall.blacklist import Blacklist
from QuickWall.wal import Wal


# Declare the logger
logger = Logger("SetPaper")


class SetPaper:
    """
    Download the wallpaper and set it using nitrogen.
    """
    def __init__(
                    self,
                    entity_list,
                    setter, passed_dir="~/.cache/QuickWall",
                    disable_blacklist=False,
                    disable_theme=False
                ):
        self.entity_list = entity_list
        self._dir_path = Path(passed_dir).expanduser()
        self._exists()
        makedirs(self._dir_path, exist_ok=True)
        self.setter_type = setter  # Update by calling the following function
Exemple #2
0
                         PictureType)
from mutagen.mp3 import MP3
from mutagen.mp4 import MP4, MP4Cover
from mutagen import File
from mutagen.flac import Picture
from base64 import b64encode
import requests
import os
from rich.prompt import Prompt

from ytmdl import prepend, defaults
from simber import Logger
from ytmdl.meta import preconfig
# import traceback

logger = Logger("song")

# ----------------------cover--------------------


def dwCover(song):
    """Download the song cover img from itunes."""
    # Try to download the cover art as cover.jpg in temp
    logger.info("Preparing the album cover")
    try:
        imgURL = song.artwork_url_100

        # Check if the passed imgURL is a local file
        # this is possible if the metadata was entered manually.
        imgURL = os.path.expanduser(imgURL)
        if os.path.exists(imgURL):
Exemple #3
0
# values that specifies wich API providers to use for getting
# the song metadata. Available values right now are:
# "{{supported_providers}}".
# Please check the github page of ytmdl for more information.
#
#METADATA_PROVIDERS = "itunes, gaana"
#
#*****************************************#
# The DEFAULT_FORMAT denotes what to use as default for downloading.
# Available values are:
# "{{supported_formats}}"
#
#DEFAULT_FORMAT = "mp3"
#'''

logger = Logger("config")


class DEFAULTS:
    """Some default stuff defined."""
    def __init__(self):
        # The home dir
        self.HOME_DIR = os.path.expanduser('~')

        # The default song dir
        self.SONG_DIR = self._get_music_dir()

        # The temp dir
        self.SONG_TEMP_DIR = os.path.join(self.SONG_DIR, 'ytmdl')

        # The default song quality
Exemple #4
0
"""All utility related functions defined here"""

import subprocess

from pathlib import Path
from shutil import rmtree
from os import mkdir, path, environ
from sys import platform
from distutils.dir_util import copy_tree

from simber import Logger

# Declare logger
logger = Logger("Utility")


def is_nitrogen():
    """
    Check if nitrogen is present or not
    """
    command = "nitrogen --help"
    p = subprocess.Popen(command.split(' '), stdout=subprocess.PIPE)
    ret, err = p.communicate()

    return True if err is None else False


def is_feh():
    """
    Check if feh is installed.
    """
Exemple #5
0
"""Handle inserting metadata manually."""

from datetime import datetime
from simber import Logger
from re import sub, match

logger = Logger("manual")


class Meta:
    """
    Meta Class will have properties same as
    those of Gaana and Itunes in order to make
    them compatible with the other modules
    that are using this data to write to the
    song files.

    Following properties will only be present

    release_date        : Date of Release of the song
    track_name          : Name of the song
    artist_name         : Name of the artist(s)
    collection_name     : Name of the album
    primary_genre_name  : Genre of the song
    track_number        : Number of the track in the album
    artwork_url_100     : URL of the album cover
    """
    def __init__(self):
        self.release_date = "{}T00:00:00Z".format(datetime.now().date())
        self.track_name = "N/A"
        self.artist_name = "N/A"
Exemple #6
0
"""All code related to setting wallpaper in xfce is defined here."""

import os
from pathlib import Path
from bs4 import BeautifulSoup
from simber import Logger

logger = Logger("XFCE")


class XFCESetter:
    def __init__(self):
        self.cmd = "xfconf-query -c xfce4-desktop -p {wallpaper_image} -s {wallpaper}"
        # Save the value of the previous wallpaper.
        self._extract_prev_wall()

    def _extract_prev_wall(self):
        """Extract the saved wallpaper from the xml file."""
        FILE = Path(
            "~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-desktop.xml"
        ).expanduser()
        try:
            soup = BeautifulSoup(open(FILE, 'r'), features="html.parser")
            wall = soup.find("property", attrs={"name": "last-image"})
        except FileNotFoundError:
            logger.warning(
                "{}: Not found. Wallpaper will not be restored!".format(FILE))
            return
        except Exception as e:
            logger.error(
                "While extracting the wallpaper, error thrown: {}".format(e))
Exemple #7
0
"""Handle extracting the issues

Extract all the comments from the issues in the
given repo and accordingly return the messages.
"""

from requests import Session, get
from simber import Logger
from repostatus.url_handler import URLHandler, update_header_token
from repostatus import Default

from typing import List, Dict

logger = Logger("issue")


def _get_comments_each(comment_url: str, token: Dict = None) -> List:
    """Get the comments from the passed URL and return a
    list containing those.

    Each issue has some comments excluding the one added when
    the issue was created.
    """
    access_token = Default.token_header if token is None else token
    response = get(comment_url, headers=access_token)
    comments = []

    if response.status_code != 200 or not len(response.json()):
        return comments

    comments = [comment["body"] for comment in response.json()]
Exemple #8
0
"""Handle requests related to repo.

Everything related to the repo like getting
details etc will be handled through this module.
"""

from pydantic import BaseModel
from requests import get
from typing import List, Optional, Dict
from fastapi import HTTPException, APIRouter, Header
from simber import Logger

from repostatus import Default

router = APIRouter()
logger = Logger("repo_handler")


class Repo(BaseModel):
    name: str
    full_name: str
    language: str = None
    stars: int
    url: str


def get_repo_list(username: str, headers: Dict) -> List:
    """Get the list of public repos for the username
    passed.

    Use the official GitHub API with the access token
Exemple #9
0
    open_archive_stream,
    is_present_in_archive,
    add_song_to_archive
)
from ytmdl.utils.ytdl import is_ytdl_config_present
from ytmdl.yt import is_yt_url
from ytmdl.__version__ import __version__

# init colorama for windows
init()

LOGGER_OUTTEMPLATE = " %a{}==>{}%".format(Style.BRIGHT, Style.RESET_ALL)
LOGGER_FILEFORMAT = "[{logger}]:[{time}]: "
logger = Logger('ytmdl',
                log_path=path.join(xdg_cache_home, 'ytmdl/logs/log.cat'),
                format=LOGGER_OUTTEMPLATE,
                file_format=LOGGER_FILEFORMAT,
                update_all=True
                )


def arguments():
    """Parse the arguments."""
    parser = argparse.ArgumentParser()

    parser.add_argument('SONG_NAME', help="Name of the song to download.\
                         Can be an URL to a playlist as well. It will be\
                         automatically recognized.",
                        type=str, nargs="*")
    parser.add_argument('-q', '--quiet',
                        help="Don't ask the user to select songs\
                        if more than one search result.\
Exemple #10
0
"""Set the theme extracted from the wallpaper."""

from pywal import (
    colors, export, sequences, theme, settings
)
import os
from simber import Logger

logger = Logger("wal")


class Wal:
    """Change the theme based on the passed wallpaper"""

    def set(self, wallpaper):
        logger.debug("{}".format(wallpaper))
        self.colors_plain = colors.get(wallpaper)
        sequences.send(self.colors_plain, to_send=True)
        colors.palette()

    def save(self):
        export.every(self.colors_plain)

    def restore(self):
        self.colors_plain = theme.file(os.path.join(
            settings.CACHE_DIR,
            "colors.json"
        ))
        sequences.send(self.colors_plain, to_send=True)
"""Handle the callback router that will help
with completion of the oauth.
"""

from fastapi import APIRouter, HTTPException, Query
from fastapi.responses import HTMLResponse
from pymongo import MongoClient
from simber import Logger
from requests import post

from config import get_settings
from assets.html import get_html

logger = Logger("callback_handler", level="DEBUG")
router = APIRouter()

REPOSTATUSDB_URI = get_settings().repostatusdb_uri
client = MongoClient(REPOSTATUSDB_URI)
db = client.repostatus


def is_state_present(state: str) -> bool:
    """Check if the state is present in the database."""
    match = db.sessionstate.find_one({"state": state})
    return True if match else False


def exchange_token(code: str, state: str) -> str:
    """Use the code provided and get the access token.

    Return the access token, once fetched.
Exemple #12
0
from pathlib import Path

from QuickWall.SetPaper import SetPaper
from QuickWall.utility import (is_nitrogen, clear_cache, migrate_to_new_loc)
from simber import Logger
from QuickWall.setter import WallSetter
from QuickWall.wall import Wall

from QuickWall.blacklist import Blacklist

# Declare the logger
LOGGER_OUTTEMPLATE = "%a[{logger}]%"
LOGGER_FILEFORMAT = "[{logger}] [{levelname}] [{time}] [{lineno}]"
logger = Logger("main",
                log_path=Path('~/.cache/QuickWall/logs/log.cat').expanduser(),
                format=LOGGER_OUTTEMPLATE,
                file_format=LOGGER_FILEFORMAT,
                update_all=True)


def parse():
    """Parse the arguments."""
    parser = argparse.ArgumentParser(description="QuickWall - Quickly set\
                                     latest wallpapers from Unsplash\
                                     directly from the commandline.",
                                     epilog="If you find any bugs, feel\
                                     free to raise an issue in the GitHub\
                                     [https://github.com/deepjyoti30/QuickWall] page."
                                     )
    parser.add_argument('--version',
                        action='version',
Exemple #13
0
"""Functions related to nitrogen."""

import subprocess

from simber import Logger

# Declare logger
logger = Logger("nitrogen")


class nitrogen:
    """
    Class to use nitrogen to set wallpapers.
    """
    def restore(self):
        """
        Restore the wallpaper using nitrogen.
        """
        logger.info("Restoring the last wallpaper...")
        c = 'nitrogen --restore'
        subprocess.Popen(c.split(), stdout=subprocess.PIPE)

    def set(self, file_path):
        """
        Set the wallpaper temporaririly
        """
        c = 'nitrogen --set-zoom-fill {}'.format(file_path)
        p = subprocess.Popen(c.split(' '), stdout=subprocess.PIPE)
        ret, err = p.communicate()

    def set_perm(self, file_path):
Exemple #14
0
"""Handle getting list of repositories and commits and messages.

Fetches a list of repos and commits along with,
its messages

Author:Vedant Baviskar
Date: 27/10/2020
"""

from requests import Session
from repostatus.url_handler import URLHandler, update_header_token
from typing import List
from simber import Logger


logger = Logger("commits")


def get_commit(commit_url: str, token: str = None) -> List:
    """Use api to return the commits and the messages."""
    commits_request = URLHandler(commit_url).commit_request
    commits = []

    if token:
        update_header_token(commits_request, token)

    # We need to make the same request 5 times in order to
    # get 500 commit messages
    for request_number in range(5):
        commits_request.url += "&page={}".format(request_number + 1)
        response = Session().send(commits_request)
Exemple #15
0
"""
Handle the archive related feature.
"""

from pathlib import Path
from typing import List, Union
from simber import Logger
from io import TextIOWrapper

from ytmdl.yt import extract_video_id

# Create logger
logger = Logger("archive")


def open_archive_stream(file: str) -> Union[List, TextIOWrapper]:
    """
    Read the archive file and extract all the videoId's
    passed. This file will be read as text and should contain
    videoId's in each line.
    """
    file_path: Path = Path(file).expanduser()

    # Check if the file exists
    if not file_path.exists():
        logger.critical("Passed archive file does not exist. Exiting!")

    stream: TextIOWrapper = file_path.open("r+")
    file_content: List = stream.read().split("\n")
    return file_content, stream
Exemple #16
0
"""All blacklist related functions."""

from pathlib import Path

from simber import Logger

# Declare logger
logger = Logger("blacklist")


class Blacklist:
    """
    Functions to be used related to blacklist.
    """
    def __init__(self, unique_id):
        self.blacklist_path = Path('~/.cache/QuickWall/blacklist').expanduser()
        self.unique_id = unique_id

    def is_blacklisted(self):
        """
        Check if the passed unique_id is available in the blacklist.
        """

        if not self.blacklist_path.exists():
            return False

        blacklist = open(self.blacklist_path).read().split('\n')[1:]

        logger.debug(str(blacklist))

        if self.unique_id in blacklist:
Exemple #17
0
"""Set wallpapers in KDE."""

import dbus
from os import path, system
from shutil import copy

from simber import Logger
logger = Logger("KDE")


def setwallpaper(filepath):
    """
    This script is taken from https://github.com/pashazz/ksetwallpaper/

    All the credit goes to the user for the code, I'm just using it
    to add a functionality to my app.
    """

    jscript = """var allDesktops = desktops();
    for ( i = 0; i < allDesktops.length;i++ ) {
        d = allDesktops[i];
        d.wallpaperPlugin = "org.kde.image";
        d.currentConfigGroup = Array("Wallpaper", "org.kde.image", "General");
        d.writeConfig("Image", "file://%s")
    }
    """
    bus = dbus.SessionBus()
    plasma = dbus.Interface(bus.get_object('org.kde.plasmashell', '/PlasmaShell'), dbus_interface='org.kde.PlasmaShell')
    plasma.evaluateScript(jscript % filepath)

Exemple #18
0
import subprocess
from pathlib import Path
from simber import Logger

logger = Logger("GNOME")


class GNOMESetter:
    def __init__(self):
        self.cmd = "gsettings set org.gnome.desktop.background picture-uri file://{wallpaper}"
        self._extract_prev_wall()

    def _extract_prev_wall(self):
        """Extract the saved wallpaper from the cmd line."""
        self.SAVED_WALL = subprocess.check_output(["gsettings", "get", "org.gnome.desktop.background", "picture-uri"])[1:-2].decode('utf-8')

    def set(self, wallpaper):
        """Set the wallpaper temporarily."""
        subprocess.call(self.cmd.format(wallpaper=wallpaper).split(" "))

    def set_perm(self, wallpaper):
        """Set the wallpaper permanently."""
        self.set(wallpaper)

    def restore(self):
        """Restore the saved wallpaper."""
        self.set_perm(self.SAVED_WALL)
Exemple #19
0
"""Setter related functions."""

from QuickWall.nitrogen import nitrogen
from QuickWall.feh import feh
from QuickWall.kde import KDEsetpaper
from QuickWall.xfce import XFCESetter
from QuickWall.gnome import GNOMESetter
from simber import Logger
from QuickWall.utility import get_desktop_environment

# Declare the logger
logger = Logger("Setter")

LockscreenCompatibleSetters = ["kde"]


class WallSetter:
    """
    Select the wallpaper setter.
    """
    def __init__(self, setter_type, lockscreen=False):
        self.setter_type = setter_type
        self.available_setters = {
                                'nitrogen': nitrogen,
                                'feh': feh,
                                'kde': KDEsetpaper,
                                'xfce': XFCESetter,
                                'gnome': GNOMESetter,
                                }
        self.setter = None
        self._select_setter()
Exemple #20
0
import requests
from re import sub

from simber import Logger

logger = Logger('Wall')


class Wall:
    """
    Class to do tasks like downloading the wallpaper.

    URL list has 4 entries:

    desc: Description of the image
    name: Name of the user who uploaded the image
    dw_link: Download link of the image
    unique_id: ID to save the image
    """
    def __init__(self, photo_id, random=None, search=None):
        self.s_term = None
        self._acces_key = "15bcea145de0b041ec8d3b16bf805e232c83cf52d569a06708aa51f33a4f14f4"
        self._URL = "https://api.unsplash.com/photos/"
        self._URL_list = []
        self.random = random
        self.search = search
        self.id = photo_id
        self._build_URL()

    def _build_URL(self):
        """Build the URL based on the passed args."""
Exemple #21
0
"""Contain all the core functions for ytmdl"""

from typing import Union
from simber import Logger
from colorama import Fore, Style

from ytmdl import (yt, song, stringutils, defaults, utility, manual, metadata)
from ytmdl.exceptions import (DownloadError, ConvertError, NoMetaError,
                              MetadataError)

logger = Logger("core")


def search(song_name, args) -> Union[str, str]:
    """Search the song on YouTube, ask the user for an input and accordingly
    return a selected song.

    The song can be extracted either from an URL or the name. If the name is
    present, we will search on YouTube for the name, ask the user for a choice
    and accordingly return the choice.

    If the URL is present, we will extract the data from the URL and return it
    accordingly.
    """
    # Declare some default values
    YOUTUBE_LINK_BASE = "https://youtube.com{}"
    PASSED_CHOICE = args.choice
    URL = args.url
    IS_QUIET = args.quiet

    if URL is None:
Exemple #22
0
    Nishan Pantha(c) 2017-18
    [email protected]
"""

from glob import glob
import os
from ytmdl.stringutils import (remove_multiple_spaces, remove_punct,
                               compute_jaccard, remove_stopwords,
                               check_keywords)
from ytmdl.defaults import DEFAULT
from ytmdl.prepend import PREPEND
from simber import Logger
from colorama import Fore, Style

logger = Logger("cache")


class Cache:
    """The main caching component."""
    def __init__(self, directory=None):
        """Init the stuff."""
        if directory is None:
            directory = DEFAULT.SONG_DIR
            # Check the dir only if special characters are present
            if '$' in directory:
                directory = directory.split("$")[0]
        directory = os.path.expanduser(directory)
        self.directory = directory
        self.max_depth = 4
Exemple #23
0
"""Functions related to usign feh as wallpaper setter."""

import subprocess
from pathlib import Path

from simber import Logger

# Declare the logger
logger = Logger("feh")


class feh:
    def __init__(self):
        self.feh_config_path = Path('~/.fehbg').expanduser()

        # Verify feh exists
        self.__verify_feh_bg_exists()

        self.current = self._find_current()

    def __verify_feh_bg_exists(self):
        """
        If feh is not run with `feh --bg-fill` even once before then the
        .fehbg file will not be present.

        Make a check to see if the file is present, and if not then raise an
        error asking the user to run it once.
        """
        if not self.feh_config_path.exists():
            logger.critical(
                ".fehbg does not exist. Seems like feh was never used before. Run feh using `feh --bg-fill <wallpaper_file>` and try again."
Exemple #24
0
"""
Handle the stuff related to trimming the song
in order to remove the speech.
"""

from inaSpeechSegmenter import Segmenter
from warnings import filterwarnings
from os import environ, remove, rename
import ffmpeg
from simber import Logger

# Setup the logger name
logger = Logger("Trimmer")

# Remove the warnings from tensorflow
environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
# Ignore warnings
filterwarnings("ignore")


class Trim:
    """
    Class that will handle the processing of the files.

    filename: File that we want to process.

    We will run the speech segmenter on it and get
    the music timestamps. Once we have the stamps, we can just
    trim the music part from the song and keep the name same.
    """
    def __init__(self, filename):
Exemple #25
0
"""Handle creation of the URL's"""

from re import match
from simber import Logger
from requests.models import PreparedRequest
from requests import Request
from repostatus import Default

logger = Logger("url_handler")


class URLHandler(object):
    """Handle dynamic creation of URL's for the GitHub API.

    The URL's will be created based on the necessity of the
    request.
    """
    def __init__(self, repo: str) -> None:
        self.repo = self._verify_repo(repo)
        self._BASE_URL = "https://api.github.com/"
        self._HEADERS = {
            'Accept': 'application/vnd.github.v3+json',
            'User-Agent': 'repostatus',
            'Authorization': 'Basic {}'.format(Default.basic_token)
        }
        self._type_map = {
            'issue': {
                'url': 'repos/{}/issues',
                'params': {}
            },
            'pull': {
Exemple #26
0
"""Define functions related to getting tags."""

import itunespy
import re
from ytmdl.stringutils import (remove_multiple_spaces, remove_punct,
                               compute_jaccard, remove_stopwords,
                               check_keywords)
from ytmdl import defaults
from simber import Logger
from ytmdl.meta import gaana, deezer, saavn, lastfm, musicbrainz, preconfig
from unidecode import unidecode

logger = Logger('metadata')


def _logger_provider_error(exception, name):
    """Show error if providers throw an error"""
    logger.debug('{}'.format(exception))
    logger.error("Something went wrong with {}. The program will continue with"
                 "the other providers. Please check '{}' for more details.\
            ".format(name, logger.get_log_file()))


def get_from_itunes(SONG_NAME):
    """Try to download the metadata using itunespy."""
    # Try to get the song data from itunes
    try:
        SONG_INFO = itunespy.search_track(SONG_NAME)
        return SONG_INFO
    except Exception as e:
        _logger_provider_error(e, 'iTunes')
Exemple #27
0
"""
Handle all the util functions for working with YouTube Music.
"""

from ytmusicapi import YTMusic
from simber import Logger

from ytmdl.exceptions import ExtractError

# Create logger
logger = Logger("ytmusic")


def get_title_from_ytmusic(videoId: str) -> str:
    """
    Get the title of the song from the videoID.

    Youtube actually supports Youtube videoId's
    that can be found in YouTube Music with the
    proper song title.

    This is way more effective and correct than
    extracting the title from the YouTube video.
    """
    ytmusic = YTMusic()

    details = ytmusic.get_song(videoId=videoId)

    # Check if error occured
    if details["playabilityStatus"]["status"] != "OK":
        raise ExtractError(videoId)
Exemple #28
0
"""Definition of functions that are used to interact with youtube."""

import requests
import os
import youtube_dl
from youtube_dl.utils import DownloadError
from re import match
from ytmdl import defaults, utility, stringutils
from downloader_cli.download import Download
import traceback
from sys import stdout
from youtube_search import YoutubeSearch
from simber import Logger
from ytmdl.exceptions import ExtractError

logger = Logger("yt")


def get_youtube_streams(url):
    """Get both audio & video stream urls for youtube using youtube-dl.

    PS: I don't know how youtube-dl does the magic
    """
    cli = "youtube-dl -g {}".format(url)
    output, error = utility.exe(cli)
    stream_urls = output.split("\n")

    url = stream_urls[1]
    return url

Exemple #29
0
"""All directory handling definitions."""

import os
import glob
import shutil
from html import unescape
from re import sub

from ytmdl import defaults
from simber import Logger

logger = Logger("Dir")


def __replace_special_characters(passed_name: str) -> str:
    """
    In the passed name, replace the special characters like
    / with a `-` so that it does not raise any errors
    related to the OS while moving the file
    """
    # TODO: Also add support for removing backslash
    return sub(r'/', '-', passed_name)


def cleanup(TRACK_INFO, index, datatype, remove_cached=True):
    """Move the song from temp to the song dir."""
    try:
        SONG = glob.glob(
            os.path.join(defaults.DEFAULT.SONG_TEMP_DIR,
                         '*{}'.format(datatype)))
        SONG = SONG[0]
Exemple #30
0
"""Handle the package as a whole. This should be
the entrypoint for everyone accessing this package
to get the happiness status.
"""
from textblob import TextBlob
from repostatus.filter import filter
from repostatus.issues import get_issue_comments
from repostatus.pulls import get_pull_comments
from repostatus.message import get_commit
from simber import Logger
from requests import Session
from typing import List, Dict

from repostatus.url_handler import URLHandler, update_header_token

logger = Logger("happiness")


class HappinessContainer(object):
    """Contain the happiness related data in
    a nice manner so that it's easier to access
    """
    def __init__(self, data: List = [], polarity: float = None) -> None:
        self.__data = data
        self.__polarity = polarity
        self.__emotion = self.__map_emotions(polarity)
        self.__data_compiled = None
        self.__color_emotion_map = {
            "angry": {
                "hex": "#F44336",
                "name": "red"