1
0
mirror of https://github.com/ellmau/nixos.git synced 2025-12-19 09:29:36 +01:00

Various fixes, local-overlay added, added one local package to local overlay

Signed-off-by: Stefan Ellmauthaler <stefan.ellmauthaler@tu-dresden.de>
This commit is contained in:
Stefan Ellmauthaler 2021-11-06 13:33:06 +01:00
parent be87a34a34
commit eeed4387a2
7 changed files with 253 additions and 4 deletions

View File

@ -2,7 +2,7 @@
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running nixos-help).
{ pkgs, name, flakes, ... }:
{ pkgs, name, flakes, flakeOutputs, ... }:
{ config, pkgs, ...}:
{
imports =
@ -54,7 +54,7 @@
experimental-features = nix-command flakes
'';
nixpkgs.overlays = [ flakes.emacs-overlay.overlay ];
nixpkgs.overlays = [ flakes.emacs-overlay.overlay flakeOutputs.overlay ];
# Enable the X11 windowing system.
services.xserver.enable = true;

View File

@ -7,7 +7,7 @@
extraModules = if args ? extraModules then args.extraModules else [ ];
extraOverlays = if args ? extraOverlays then args.extraOverlays else [ ];
pkgs = flakes.nixpkgs;
configuration = import ./configuration.nix {inherit extraOverlays system pkgs name flakes;} ;
configuration = import ./configuration.nix {inherit extraOverlays system pkgs name flakes flakeOutputs;} ;
in
{
inherit name;

View File

@ -23,6 +23,7 @@
outputs = {self, ...}@inputs:
let outputs = rec {
overlay = import ./local-overlay;
nixosConfigurations = import self {
flakes = inputs;
flakeOutputs = outputs;

View File

@ -0,0 +1,4 @@
final: prev:
{
tray-calendar = final.callPackage ./pkgs/tray-calendar {};
}

View File

@ -0,0 +1,29 @@
{ stdenv
, python3
, gtk3
, gobject-introspection
, wrapGAppsHook
, lib
}:
stdenv.mkDerivation rec {
pname = "tray-calendar";
version = "0.9";
src = ./traycalendar.py;
buildInputs = [
(python3.withPackages (pyPkgs: with pyPkgs; [
pygobject3
]))
gtk3
gobject-introspection
];
nativeBuildInputs = [ wrapGAppsHook ];
dontUnpack = true;
installPhase = "install -m755 -D $src $out/bin/traycalendar";
meta = {
license = lib.licenses.gpl3Only;
homepage = "https://github.com/vifon/TrayCalendar";
};
}

View File

@ -0,0 +1,215 @@
#!/usr/bin/env python3
########################################################################
# Copyright (C) 2015-2018 Wojciech Siewierski #
# #
# This program 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. #
# #
# This program 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 this program. If not, see <http://www.gnu.org/licenses/>. #
########################################################################
import functools
import glob
import os.path
import re
from collections import defaultdict
from os import getenv
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk
DEFAULT_ORG_DIRECTORY = os.path.join(getenv('HOME'), "org")
ORG_GLOB = '*.org'
ORG_ARCHIVE_SUFFIX = '_archive.org'
def org_agenda_files(directory):
org_abs = functools.partial(os.path.join, directory)
agenda_files_path = org_abs('.agenda-files')
try:
with open(agenda_files_path) as agenda_files:
yield from (org_abs(f.rstrip('\n')) for f in agenda_files)
except FileNotFoundError:
for filename in glob.iglob(os.path.join(directory, ORG_GLOB)):
if not filename.endswith(ORG_ARCHIVE_SUFFIX):
yield filename
def scan_org_for_events(org_directories):
"""Search the org files for the calendar events.
Scans the passed directories for the .org files and saves the events
found there into a multilevel dict of lists: events[year][month][day]
The returned dict uses defaultdict so *do not* rely on the
KeyError exception etc.! Check if the element exists with
.get(key) before accessing it!
"""
def year_dict():
return defaultdict(month_dict)
def month_dict():
return defaultdict(day_dict)
def day_dict():
return defaultdict(event_list)
def event_list():
return list()
events = year_dict()
for org_directory in org_directories:
for filename in org_agenda_files(org_directory):
with open(filename, "r") as filehandle:
last_heading = None
for line in filehandle:
heading_match = re.search(r'^\*+\s+(.*)', line)
if heading_match:
last_heading = heading_match.group(1)
# strip the tags
last_heading = re.sub(r'\s*\S*$', last_heading, '')
match = re.search(r'<(\d{4})-(\d{2})-(\d{2}).*?>', line)
if match:
year, month, day = [ int(field) for field in match.group(1,2,3) ]
month -= 1 # months are indexed from 0 in Gtk.Calendar
events[year][month][day].append(last_heading)
return events
class CalendarWindow(object):
def __init__(self, org_directories):
self.window = Gtk.Window()
self.window.set_wmclass("traycalendar", "TrayCalendar")
self.window.set_resizable(False)
self.window.set_decorated(False)
self.window.set_gravity(Gdk.Gravity.STATIC)
window_width = 300
# Set the window geometry.
geometry = Gdk.Geometry()
geometry.min_width = window_width
geometry.max_width = window_width
geometry.base_width = window_width
self.window.set_geometry_hints(
None, geometry,
Gdk.WindowHints.MIN_SIZE |
Gdk.WindowHints.MAX_SIZE |
Gdk.WindowHints.BASE_SIZE)
# Create the listview for the calendar events.
list_model = Gtk.ListStore(str)
list_view = Gtk.TreeView(list_model)
list_column = Gtk.TreeViewColumn("Events", Gtk.CellRendererText(), text=0)
list_column.set_fixed_width(window_width)
list_view.append_column(list_column)
# Create the calendar widget.
calendar = Gtk.Calendar()
self.calendar_events = scan_org_for_events(org_directories)
calendar.connect('month-changed', self.mark_calendar_events)
calendar.connect('day-selected', self.display_event_list, list_model)
self.mark_calendar_events(calendar)
self.display_event_list(calendar, list_model)
close_button = Gtk.Button("Close")
close_button.connect('clicked', lambda event: self.window.destroy())
vbox = Gtk.VBox()
vbox.add(close_button)
vbox.add(calendar)
vbox.add(list_view)
self.window.add(vbox)
rootwin = self.window.get_screen().get_root_window()
# get_pointer is deprecated but using Gdk.Device.get_position
# is not viable here: we have no access to the pointing device.
screen, x, y, mask = rootwin.get_pointer()
x -= window_width
# Show the window right beside the cursor.
self.window.move(x,y)
self.window.show_all()
def mark_calendar_events(self, calendar):
"""Update the days with calendar events list for the selected month."""
year, month, day = calendar.get_date()
calendar.freeze_notify()
calendar.clear_marks()
for day in self.calendar_events[year][month]:
calendar.mark_day(day)
calendar.thaw_notify()
def display_event_list(self, calendar, event_list):
"""Update the calendar event list for the selected day."""
year, month, day = calendar.get_date()
event_list.clear()
# get(day) used instead of [day] because we use defaultdict
# and it would create a new element.
events = self.calendar_events[year][month].get(day)
if events:
for event in events:
event_list.append([event])
def tray_mode(org_directories):
def on_left_click(event):
window = CalendarWindow(org_directories)
def on_right_click(button, time, data):
Gtk.main_quit()
statusicon = Gtk.StatusIcon()
statusicon.set_from_icon_name('x-office-calendar')
statusicon.connect('activate', on_left_click)
statusicon.connect('popup-menu', on_right_click)
Gtk.main()
def window_mode(org_directories):
window = CalendarWindow(org_directories)
window.window.connect('destroy', Gtk.main_quit)
Gtk.main()
def main(argv=None):
import argparse
parser = argparse.ArgumentParser()
parser.add_argument(
"--no-tray",
help="Show the calendar windows immediately and quit after it's closed.",
action='store_true',
)
parser.add_argument(
"--org-directory", "-d",
help="Directories to search for *.org; default: ~/org/.",
action='append',
dest='org_directories',
)
args = parser.parse_args()
if not args.org_directories:
args.org_directories = [DEFAULT_ORG_DIRECTORY]
if args.no_tray:
window_mode(args.org_directories)
else:
tray_mode(args.org_directories)
if __name__ == "__main__":
from sys import argv
# workaround for a pygobject bug
import signal
signal.signal(signal.SIGINT, signal.SIG_DFL)
main(argv)

View File

@ -233,7 +233,7 @@
#format-prefix-foreground = foreground_altcol;
format-underline = "#0a6cf5";
label = "%date% %time%";
label = "%{A1:${pkgs.tray-calendar}/bin/traycalendar --no-tray:}%{A} %date% %time%";
};
"module/battery" = {
type = "internal/battery";