Compare commits
65 Commits
xthursdayx
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0100e6551e | ||
|
|
0c892827c1 | ||
|
|
4089f17801 | ||
|
|
76861d894a | ||
|
|
d2be99348d | ||
|
|
36d61330d7 | ||
|
|
ae9f3abc6f | ||
|
|
e4e91f1b04 | ||
|
|
b3a130c96f | ||
|
|
8e2004efbc | ||
|
|
2aba3a2a3f | ||
|
|
cbb03a223c | ||
|
|
0943bc6122 | ||
|
|
92b9821f18 | ||
|
|
9b90659f33 | ||
|
|
4358bd903e | ||
|
|
73fad69e04 | ||
|
|
c67ecbec8c | ||
|
|
4911c9360c | ||
|
|
6f851a2f39 | ||
|
|
2788f466b6 | ||
|
|
fb0463a528 | ||
|
|
aa9fc20b8b | ||
|
|
a44c07e616 | ||
|
|
35dca53357 | ||
|
|
b5d2059c9a | ||
|
|
7ebe8cf8f4 | ||
|
|
065d4a9b64 | ||
|
|
326c9ce5cb | ||
|
|
82345758f7 | ||
|
|
f465383805 | ||
|
|
3dd9f772a4 | ||
|
|
9b4db63f07 | ||
|
|
2e13ba7452 | ||
|
|
324c050054 | ||
|
|
0646b07d07 | ||
|
|
30c59d8d7f | ||
|
|
c005b239c0 | ||
|
|
1e814c5b05 | ||
|
|
e27455a7a1 | ||
|
|
ca505bdeec | ||
|
|
7f3ed2c5cc | ||
|
|
c3795875e1 | ||
|
|
f5c04d7c7b | ||
|
|
82022ad5f8 | ||
|
|
4825adbd63 | ||
|
|
6ef38a4ac2 | ||
|
|
05349050cb | ||
|
|
d05c9eca42 | ||
|
|
0f8df5a65f | ||
|
|
069319dec5 | ||
|
|
4e1a367590 | ||
|
|
a57afe85ff | ||
|
|
7e75e1b90d | ||
|
|
b761de7722 | ||
|
|
71c5dfb02c | ||
|
|
f25eebf009 | ||
|
|
a9816f99d5 | ||
|
|
17fa945473 | ||
|
|
350fcfd000 | ||
|
|
f59faedf1d | ||
|
|
648a79b8c2 | ||
|
|
8e5c51b1ad | ||
|
|
388ae5df25 | ||
|
|
a53902c85b |
17
.github/stale.yml
vendored
Normal file
17
.github/stale.yml
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 60
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 7
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- pinned
|
||||
- security
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: wontfix
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed if no further activity occurs. Thank you
|
||||
for your contributions.
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: false
|
||||
4
.github/workflows/publish.yaml
vendored
4
.github/workflows/publish.yaml
vendored
@@ -12,11 +12,11 @@ jobs:
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_HUB_TOKEN }}
|
||||
username: ${{ secrets.DOCKER_HUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_HUB_TOKEN }}
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
- name: Publish container to Docker Hub
|
||||
run: docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6 --tag "mtoohey/standardnotes-extensions:$(git log -1 --format="%H" | cut -c -6)" --tag mtoohey/standardnotes-extensions:latest --push .
|
||||
run: docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6 --tag "${{ secrets.DOCKER_HUB_USERNAME }}/standardnotes-extensions:$(git log -1 --format="%H" | cut -c -6)" --tag ${{ secrets.DOCKER_HUB_USERNAME }}/standardnotes-extensions:latest --push .
|
||||
|
||||
41
README.md
41
README.md
@@ -1,9 +1,9 @@
|
||||

|
||||
|
||||
## Standard Notes Extensions - Self-Hosted Repository
|
||||
Host Standard Notes extensions on your own server. This utility parses most of the open-source extensions available from original repository as well as from other authors and builds an extensions repository which then can be plugged directly into Standard Notes Web/Desktop Clients. (https://standardnotes.org/)
|
||||
Host Standard Notes extensions on your own server. This utility parses most of the open-source extensions available from the Standard Notes team as well as a range of extensions created by the wider Standard Notes community to build an extensions repository which can then be plugged directly into Standard Notes Web/Desktop Clients. (https://standardnotes.org/)
|
||||
|
||||
Extensions are listed as YAML in the `\extensions` sub-directory, pull a request if you'd like to add yours.
|
||||
Extensions are listed as `YAML` in the `/extensions` sub-directory, pull a request if you'd like to add yours.
|
||||
|
||||
### Requirements
|
||||
* Python 3
|
||||
@@ -17,15 +17,19 @@ Extensions are listed as YAML in the `\extensions` sub-directory, pull a request
|
||||
|
||||
### Usage
|
||||
|
||||
* Clone this repository to the web-server:
|
||||
|
||||
* Clone this repository to your web-server:
|
||||
```bash
|
||||
$ git clone https://github.com/iganeshk/standardnotes-extensions.git
|
||||
$ cd standardnotes-extensions
|
||||
$ pip3 install -r requirements.txt
|
||||
```
|
||||
* Visit the following link to generate a personal access token:
|
||||
```
|
||||
$ https://github.com/settings/tokens
|
||||
```
|
||||

|
||||
|
||||
* Use the env.sample to create a .env file for your environment variables. The utility will automatically load these when it starts.
|
||||
* Use the provided [`env.sample`](../env.sample) to create a `.env` file for your environment variables and including your Github personal access token.
|
||||
|
||||
```
|
||||
# Sample ENV setup Variables (YAML)
|
||||
@@ -47,35 +51,36 @@ github:
|
||||
|
||||
```
|
||||
|
||||
* [Optional] Make additions or appropriate changes in `/extensions` directory.
|
||||
* [Optional] Add more extensions to the `/extensions` directory, using the `YAML` sample templates for [extensions](../extension.yaml.sample) or [themes](../theme.yaml.sample), or modify any existing extensions.
|
||||
* Run the utility:
|
||||
|
||||
```bash
|
||||
$ python3 build_repo.py
|
||||
```
|
||||
* Serve the `/public` directory and verify if the endpoint is reachable.
|
||||
* Serve the `/public` directory and verify that the endpoint is reachable.
|
||||
|
||||
```
|
||||
https://your-domain.com/extensions/index.json
|
||||
```
|
||||
* Import the above endpoint into the web/desktop client. (Note: Enable CORS for your web server respectively, nginx setup provided below)
|
||||
* Import the `latest url` for each extension you want to add (for example: `https://your-domaim.com/extensions/bold-editor/index.json`) into the Standard Notes Web Desktop client under the `General` > `Advanced Settings` > `Install Custom Extension` menu. (Note: Enable CORS for your web server respectively, nginx setup provided below)
|
||||
|
||||
### Docker
|
||||
|
||||
* To via Docker, clone the repository, set up the .env file, and optionally modify the `extensions` directory, following the instructions above.
|
||||
* Then pull and run run the container, specifying the mount points for the `.env` file, the `extensions` directory, and the `public` directory, where the output will be placed:
|
||||
* To run via Docker, clone this repository, create your `.env` file using the provided `env.sample`, and optionally add any additional extensions to the `/extensions` directory, following the instructions above.
|
||||
* Then pull and run the container, specifying the mount points for the `.env` file, the `extensions` directory, and the `public` directory, where the self-hosted extensions will be placed:
|
||||
|
||||
```bash
|
||||
$ docker run \
|
||||
-v $PWD/.env:/build/.env \
|
||||
-v $PWD/extensions:/build/extensions \
|
||||
-v $PWD/public:/build/public \
|
||||
mtoohey/standardnotes-extensions
|
||||
-v $PWD/standardnotes-extensions-list.txt:/build/standardnotes-extensions-list.txt \
|
||||
iganesh/standardnotes-extensions
|
||||
```
|
||||
|
||||
#### Docker Compose
|
||||
|
||||
If you would like to use the container with docker-compose, the exact setup will be somewhat specific to your configuration, however the following snippet may be helpful, assuming you have cloned this repository in your `$HOME` directory and followed the instructions regarding the .env file and `extensions` directory:
|
||||
If you would like to use the container with docker-compose, the exact setup will be somewhat specific to your configuration, however the following snippet may be helpful, assuming you have cloned this repository in your `$HOME` directory and followed the instructions regarding the `.env` file and `/extensions` directory:
|
||||
|
||||
```yaml
|
||||
version: '3.3'
|
||||
@@ -86,11 +91,12 @@ services:
|
||||
- standardnotes-extensions:/usr/share/nginx/html
|
||||
|
||||
standardnotes-extensions:
|
||||
image: mtoohey/standardnotes-extensions
|
||||
image: iganesh/standardnotes-extensions
|
||||
restart: "no"
|
||||
volumes:
|
||||
- $HOME/standardnotes-extensions/.env:/build/.env
|
||||
- $HOME/standardnotes-extensions/extensions:/build/extensions
|
||||
- $HOME/standardnotes-extensions/standardnotes-extensions-list.txt:/build/standardnotes-extensions-list.txt
|
||||
- standardnotes-extensions:/build/public
|
||||
|
||||
volumes:
|
||||
@@ -107,7 +113,7 @@ Also, please note that the configuration snippet above is in no way a complete s
|
||||
If you need to build the container, clone this repository, `cd` into it, and run the following command:
|
||||
|
||||
```bash
|
||||
$ docker build -t standardnotes-extensions .
|
||||
$ docker build --no-cache -t standardnotes-extensions:local .
|
||||
```
|
||||
|
||||
### Setup with nginx
|
||||
@@ -123,7 +129,7 @@ $ docker build -t standardnotes-extensions .
|
||||
#
|
||||
# Custom headers and headers various browsers *should* be OK with but aren't
|
||||
#
|
||||
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
|
||||
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,X-Application-Version,X-SNJS-Version';
|
||||
#
|
||||
# Tell client that this pre-flight info is valid for 20 days
|
||||
#
|
||||
@@ -135,13 +141,13 @@ $ docker build -t standardnotes-extensions .
|
||||
if ($request_method = 'POST') {
|
||||
add_header 'Access-Control-Allow-Origin' '*';
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
|
||||
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
|
||||
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,X-Application-Version,X-SNJS-Version';
|
||||
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
|
||||
}
|
||||
if ($request_method = 'GET') {
|
||||
add_header 'Access-Control-Allow-Origin' '*';
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
|
||||
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
|
||||
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,X-Application-Version,X-SNJS-Version';
|
||||
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
|
||||
}
|
||||
}
|
||||
@@ -151,4 +157,3 @@ $ docker build -t standardnotes-extensions .
|
||||
* This project was adapted originally from https://github.com/JokerQyou/snextensions
|
||||
* Check out https://github.com/jonhadfield/awesome-standard-notes for more Standard Notes stuff!
|
||||
* Authors of custom themes and extensions
|
||||
|
||||
|
||||
236
build_repo.py
236
build_repo.py
@@ -17,25 +17,39 @@ import os
|
||||
import json
|
||||
import shutil
|
||||
from zipfile import ZipFile
|
||||
from socket import gethostname as getlocalhostname
|
||||
import requests
|
||||
import yaml
|
||||
|
||||
LOCAL_HOSTNAME = getlocalhostname()
|
||||
|
||||
def get_environment(base_dir):
|
||||
"""
|
||||
Parse the environment variables from .env
|
||||
"""
|
||||
temp_envvar = yaml.load("""
|
||||
domain: https://domain.com/extensions
|
||||
temp_env_var = yaml.load("""
|
||||
github:
|
||||
username:
|
||||
token:
|
||||
public_dir: public
|
||||
extensions_dir: extensions
|
||||
domain: https://domain.com/extensions
|
||||
stdnotes_extensions_list: standardnotes-extensions-list.txt
|
||||
""", Loader=yaml.FullLoader)
|
||||
env_var = {}
|
||||
if os.path.isfile(os.path.join(base_dir, ".env")):
|
||||
with open(os.path.join(base_dir, ".env")) as temp_env_file:
|
||||
temp_envvar = yaml.load(temp_env_file, Loader=yaml.FullLoader)
|
||||
env_var = yaml.load(temp_env_file, Loader=yaml.FullLoader)
|
||||
|
||||
return temp_envvar
|
||||
# if user hasn't updated the env, copy defaults to yaml dictionary
|
||||
for key in temp_env_var:
|
||||
try:
|
||||
if not env_var[key]:
|
||||
env_var[key] = temp_env_var[key]
|
||||
except KeyError as e:
|
||||
env_var[key] = temp_env_var[key]
|
||||
|
||||
return env_var
|
||||
|
||||
|
||||
def process_zipball(repo_dir, release_version):
|
||||
@@ -70,89 +84,90 @@ def process_zipball(repo_dir, release_version):
|
||||
os.remove(os.path.join(repo_dir, release_version) + ".zip")
|
||||
|
||||
|
||||
def git_clone_method(ext_yaml, public_dir, ext_has_update):
|
||||
def git_clone_method(ext_yaml, public_path, ext_has_update):
|
||||
"""
|
||||
Get the latest repository and parse for metadata
|
||||
"""
|
||||
repo_name = ext_yaml['github'].split('/')[-1]
|
||||
repo_dir = os.path.join(public_dir, repo_name)
|
||||
run([
|
||||
'git', 'clone', 'https://github.com/{github}.git'.format(**ext_yaml),
|
||||
'--quiet', '{}_tmp'.format(repo_name)
|
||||
],
|
||||
check=True)
|
||||
ext_last_commit = (run([
|
||||
'git', '--git-dir=' +
|
||||
os.path.join(public_dir, '{}_tmp'.format(repo_name), '.git'),
|
||||
'rev-list', '--tags', '--max-count=1'
|
||||
],
|
||||
stdout=PIPE,
|
||||
check=True).stdout.decode('utf-8').replace(
|
||||
"\n", ""))
|
||||
ext_version = run([
|
||||
'git', '--git-dir',
|
||||
os.path.join(public_dir, '{}_tmp'.format(repo_name), '.git'),
|
||||
'describe', '--tags', ext_last_commit
|
||||
],
|
||||
stdout=PIPE,
|
||||
check=True).stdout.decode('utf-8').replace("\n", "")
|
||||
repo_dir = os.path.join(public_path, repo_name)
|
||||
try:
|
||||
run([
|
||||
'git', 'clone', 'https://github.com/{github}.git'.format(**ext_yaml),
|
||||
'--quiet', '{}_tmp'.format(repo_name)
|
||||
],
|
||||
check=True)
|
||||
ext_last_commit = (run([
|
||||
'git', '--git-dir=' +
|
||||
os.path.join(public_path, '{}_tmp'.format(repo_name), '.git'),
|
||||
'rev-list', '--tags', '--max-count=1'
|
||||
],
|
||||
stdout=PIPE,
|
||||
check=True).stdout.decode('utf-8').replace(
|
||||
"\n", ""))
|
||||
ext_version = run([
|
||||
'git', '--git-dir',
|
||||
os.path.join(public_path, '{}_tmp'.format(repo_name), '.git'),
|
||||
'describe', '--tags', ext_last_commit
|
||||
],
|
||||
stdout=PIPE,
|
||||
check=True).stdout.decode('utf-8').replace("\n", "")
|
||||
|
||||
# check if the latest version already exist
|
||||
if not os.path.exists(os.path.join(repo_dir, ext_version)):
|
||||
ext_has_update = True
|
||||
shutil.move(
|
||||
os.path.join(public_dir, '{}_tmp'.format(repo_name)),
|
||||
os.path.join(public_dir, repo_name, '{}'.format(ext_version)))
|
||||
# Delete .git resource from the directory
|
||||
shutil.rmtree(
|
||||
os.path.join(public_dir, repo_name, '{}'.format(ext_version),
|
||||
'.git'))
|
||||
else:
|
||||
# ext already up-to-date
|
||||
# print('Extension: {} - {} (already up-to-date)'.format(ext_yaml['name'], ext_version))
|
||||
# clean-up
|
||||
shutil.rmtree(os.path.join(public_dir, '{}_tmp'.format(repo_name)))
|
||||
return ext_version, ext_has_update
|
||||
# check if the latest version already exist
|
||||
if not os.path.exists(os.path.join(repo_dir, ext_version)):
|
||||
ext_has_update = True
|
||||
shutil.move(
|
||||
os.path.join(public_path, '{}_tmp'.format(repo_name)),
|
||||
os.path.join(public_path, repo_name, '{}'.format(ext_version)))
|
||||
# Delete .git resource from the directory
|
||||
shutil.rmtree(
|
||||
os.path.join(public_path, repo_name, '{}'.format(ext_version),
|
||||
'.git'))
|
||||
else:
|
||||
# ext already up-to-date
|
||||
# print('Extension: {} - {} (already up-to-date)'.format(ext_yaml['name'], ext_version))
|
||||
# clean-up
|
||||
shutil.rmtree(os.path.join(public_path, '{}_tmp'.format(repo_name)))
|
||||
return ext_version, ext_has_update
|
||||
except Exception as e:
|
||||
print('Skipping: {:38s}\t(github repository not found)'.format(repo_name))
|
||||
return '0.0', False
|
||||
|
||||
|
||||
def parse_extensions(base_dir, base_url, ghub_session):
|
||||
def parse_extensions(base_dir, extensions_dir, public_dir, base_url, stdnotes_ext_list_path, ghub_headers):
|
||||
"""
|
||||
Build Standard Notes extensions repository using Github meta-data
|
||||
"""
|
||||
|
||||
extension_dir = os.path.join(base_dir, 'extensions')
|
||||
public_dir = os.path.join(base_dir, 'public')
|
||||
if not os.path.exists(os.path.join(public_dir)):
|
||||
os.makedirs(public_dir)
|
||||
os.chdir(public_dir)
|
||||
extension_path = extensions_dir
|
||||
public_path = public_dir
|
||||
os.chdir(public_path)
|
||||
|
||||
extensions = []
|
||||
std_ext_list = []
|
||||
std_ext_list = parse_stdnotes_extensions(stdnotes_ext_list_path)
|
||||
# Get all extensions, sort extensions alphabetically along by their by type
|
||||
extfiles = [x for x in sorted(os.listdir(extension_dir)) if not x.endswith('theme.yaml') and x.endswith('.yaml')]
|
||||
themefiles = [x for x in sorted(os.listdir(extension_dir)) if x.endswith('theme.yaml')]
|
||||
extfiles = [x for x in sorted(os.listdir(extension_path)) if not x.endswith('theme.yaml') and x.endswith('.yaml')]
|
||||
themefiles = [y for y in sorted(os.listdir(extension_path)) if y.endswith('theme.yaml')]
|
||||
extfiles.extend(themefiles)
|
||||
|
||||
for extfile in extfiles:
|
||||
with open(os.path.join(extension_dir, extfile)) as extyaml:
|
||||
with open(os.path.join(extension_path, extfile)) as extyaml:
|
||||
ext_yaml = yaml.load(extyaml, Loader=yaml.FullLoader)
|
||||
ext_has_update = False
|
||||
repo_name = ext_yaml['github'].split('/')[-1]
|
||||
repo_dir = os.path.join(public_dir, repo_name)
|
||||
|
||||
# If we don't have a Github API Session, do git-clone instead
|
||||
if ghub_session is not None:
|
||||
repo_dir = os.path.join(public_path, repo_name)
|
||||
# If we have valid github personal access token
|
||||
if ghub_headers:
|
||||
# Get extension's github release meta-data
|
||||
ext_git_info = json.loads(
|
||||
ghub_session.get(
|
||||
requests.get(
|
||||
'https://api.github.com/repos/{github}/releases/latest'.
|
||||
format(**ext_yaml)).text)
|
||||
format(**ext_yaml), headers=ghub_headers).text)
|
||||
try:
|
||||
ext_version = ext_git_info['tag_name']
|
||||
except KeyError:
|
||||
# No release's found
|
||||
print(
|
||||
"Error: Unable to update %s (%s) does it have a release at Github?"
|
||||
% (ext_yaml['name'], extfile))
|
||||
# No github releases found
|
||||
print('Skipping: {:38s}\t(github repository not found)'.format(
|
||||
ext_yaml['name']))
|
||||
continue
|
||||
# Check if extension directory already exists
|
||||
if not os.path.exists(repo_dir):
|
||||
@@ -162,7 +177,7 @@ def parse_extensions(base_dir, base_url, ghub_session):
|
||||
ext_has_update = True
|
||||
os.makedirs(os.path.join(repo_dir, ext_version))
|
||||
# Grab the release and then unpack it
|
||||
with requests.get(ext_git_info['zipball_url'],
|
||||
with requests.get(ext_git_info['zipball_url'], headers=ghub_headers,
|
||||
stream=True) as zipball_stream:
|
||||
with open(
|
||||
os.path.join(repo_dir, ext_version) + ".zip",
|
||||
@@ -172,7 +187,11 @@ def parse_extensions(base_dir, base_url, ghub_session):
|
||||
process_zipball(repo_dir, ext_version)
|
||||
else:
|
||||
ext_version, ext_has_update = git_clone_method(
|
||||
ext_yaml, public_dir, ext_has_update)
|
||||
ext_yaml, public_path, ext_has_update)
|
||||
|
||||
if extfile in std_ext_list:
|
||||
ext_id = ext_yaml['id'].rsplit('.', 1)[1]
|
||||
ext_yaml['id'] = '%s.%s' % (LOCAL_HOSTNAME, ext_id)
|
||||
|
||||
# Build extension info (stateless)
|
||||
# https://domain.com/sub-domain/my-extension/index.json
|
||||
@@ -199,33 +218,33 @@ def parse_extensions(base_dir, base_url, ghub_session):
|
||||
# Strip empty values
|
||||
extension = {k: v for k, v in extension.items() if v}
|
||||
|
||||
# Check if extension is already up-to-date ()
|
||||
# Check if extension is already up-to-date
|
||||
if ext_has_update:
|
||||
# Generate JSON file for each extension
|
||||
with open(os.path.join(public_dir, repo_name, 'index.json'),
|
||||
with open(os.path.join(public_path, repo_name, 'index.json'),
|
||||
'w') as ext_json:
|
||||
json.dump(extension, ext_json, indent=4)
|
||||
if extfile.endswith("theme.yaml"):
|
||||
print('Theme: {:34s} {:6s}\t(updated)'.format(
|
||||
ext_yaml['name'], ext_version))
|
||||
ext_yaml['name'], ext_version.strip('v')))
|
||||
else:
|
||||
print('Extension: {:30s} {:6s}\t(updated)'.format(
|
||||
ext_yaml['name'], ext_version))
|
||||
ext_yaml['name'], ext_version.strip('v')))
|
||||
else:
|
||||
# ext already up-to-date
|
||||
if extfile.endswith("theme.yaml"):
|
||||
print('Theme: {:34s} {:6s}\t(already up-to-date)'.format(
|
||||
ext_yaml['name'], ext_version))
|
||||
ext_yaml['name'], ext_version.strip('v')))
|
||||
else:
|
||||
print('Extension: {:30s} {:6s}\t(already up-to-date)'.format(
|
||||
ext_yaml['name'], ext_version))
|
||||
ext_yaml['name'], ext_version.strip('v')))
|
||||
|
||||
extensions.append(extension)
|
||||
os.chdir('..')
|
||||
|
||||
# Generate the main repository index JSON
|
||||
# https://domain.com/sub-domain/my-index.json
|
||||
with open(os.path.join(public_dir, 'index.json'), 'w') as ext_json:
|
||||
with open(os.path.join(public_path, 'index.json'), 'w') as ext_json:
|
||||
json.dump(
|
||||
dict(
|
||||
content_type='SN|Repo',
|
||||
@@ -238,46 +257,81 @@ def parse_extensions(base_dir, base_url, ghub_session):
|
||||
print("\nProcessed: {:20s}{} extensions. (Components: {}, Themes: {})".format("", len(extfiles), len(extfiles)-len(themefiles), len(themefiles)))
|
||||
print("Repository Endpoint URL: {:6s}{}/index.json".format("", base_url))
|
||||
|
||||
def parse_stdnotes_extensions(stdnotes_ext_list_path):
|
||||
"""
|
||||
To circumvent around the issue: https://github.com/standardnotes/desktop/issues/789
|
||||
We'll be parsing standard note's extensions package ids with local hostname followed
|
||||
by package name
|
||||
"""
|
||||
if not os.path.exists(stdnotes_ext_list_path):
|
||||
print("\n⚠️ WARNING: Unable to locate standard notes extensions list file, make sure you've \
|
||||
cloned the source repository properly\
|
||||
")
|
||||
print("You may encounter issues registering extensions, checkout ")
|
||||
print("https://github.com/standardnotes/desktop/issues/789 for more details\n")
|
||||
else:
|
||||
std_exts_list = []
|
||||
with open(stdnotes_ext_list_path) as list_file:
|
||||
for line in list_file:
|
||||
if not line.startswith('#'):
|
||||
std_exts_list.append(line.rstrip())
|
||||
return std_exts_list
|
||||
|
||||
|
||||
def main():
|
||||
"""
|
||||
teh main function
|
||||
"""
|
||||
base_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
# Get environment variables
|
||||
env_var = {}
|
||||
env_var = get_environment(base_dir)
|
||||
base_url = env_var['domain']
|
||||
while base_url.endswith('/'):
|
||||
base_url = base_url[:-1]
|
||||
base_url = env_var["domain"]
|
||||
extensions_dir = env_var['extensions_dir']
|
||||
if os.path.exists(os.path.join(base_dir, extensions_dir)):
|
||||
extensions_dir = os.path.join(base_dir, extensions_dir)
|
||||
else:
|
||||
print("\n⚠️ WARNING: Unable to locate extensions directory, make sure you've \
|
||||
cloned the source repository properly and try again")
|
||||
sys.exit(1)
|
||||
public_dir = env_var['public_dir']
|
||||
if os.path.exists(os.path.join(base_dir, public_dir)):
|
||||
public_dir = os.path.join(base_dir, public_dir)
|
||||
else:
|
||||
os.makedirs(os.path.join(base_dir, public_dir))
|
||||
public_dir = os.path.join(base_dir, public_dir)
|
||||
|
||||
if (env_var['github']['username'] and env_var['github']['token']):
|
||||
stdnotes_ext_list = env_var['stdnotes_extensions_list']
|
||||
stdnotes_ext_list_path = os.path.join(base_dir, stdnotes_ext_list)
|
||||
ghub_auth_complete = False
|
||||
ghub_headers = False
|
||||
|
||||
if env_var['github']['token']:
|
||||
# Get a re-usable session object using user credentials
|
||||
ghub_session = requests.Session()
|
||||
ghub_session.auth = (env_var['github']['username'],
|
||||
env_var['github']['token'])
|
||||
ghub_headers = {'Authorization': f'token %s' % env_var['github']['token']}
|
||||
try:
|
||||
ghub_verify = ghub_session.get("https://api.github.com/")
|
||||
if not ghub_verify.headers['status'] == "200 OK":
|
||||
print("Error: %s " % ghub_verify.headers['status'])
|
||||
ghub_verify = requests.get("https://api.github.com/", headers=ghub_headers)
|
||||
if not ghub_verify.status_code == 200:
|
||||
print("ERROR: %s " % ghub_verify.headers['status'])
|
||||
print(
|
||||
"Bad Github credentials in the .env file, check and try again."
|
||||
)
|
||||
sys.exit(1)
|
||||
ghub_auth_complete = True
|
||||
except Exception as e:
|
||||
print("Unknown error occurred: %s" % e)
|
||||
# Build extensions
|
||||
parse_extensions(base_dir, base_url, ghub_session)
|
||||
# Terminate Session
|
||||
ghub_session.close()
|
||||
else:
|
||||
print("ERROR: %s" % e)
|
||||
|
||||
if not ghub_auth_complete:
|
||||
# Environment file missing
|
||||
print(
|
||||
"Environment variables not set (have a look at env.sample). Using Git Clone method instead"
|
||||
"Environment variables not set (have a look at env.sample). Using git-clone method instead"
|
||||
)
|
||||
input(
|
||||
"⚠️ this is an in-efficient process, Press any key to continue:\n")
|
||||
parse_extensions(base_dir, base_url, None)
|
||||
sys.exit(0)
|
||||
"⚠️ WARNING: This is an in-efficient process\nPress any key to go ahead anyway: ")
|
||||
|
||||
# Build extensions
|
||||
parse_extensions(base_dir, extensions_dir, public_dir, base_url, stdnotes_ext_list_path, ghub_headers)
|
||||
sys.exit(0)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
19
env.sample
19
env.sample
@@ -3,14 +3,23 @@
|
||||
#
|
||||
# $ cp env.sample .env
|
||||
#
|
||||
# WARNING
|
||||
# Do not include this new file in source control
|
||||
# Github Credentials
|
||||
# Generate your token here: https://github.com/settings/tokens
|
||||
# Generate your personal access token here: https://github.com/settings/tokens
|
||||
# No additional permission required, this is just to avoid github api rate limits
|
||||
#
|
||||
|
||||
domain: https://domain.com/extensions
|
||||
|
||||
github:
|
||||
username: USERNAME
|
||||
token: TOKEN
|
||||
|
||||
# EXTENSION PUBLICATION DOMAIN
|
||||
domain: https://domain.com/extensions
|
||||
|
||||
# EXTENSIONS DIRECTORY
|
||||
extensions_dir: extensions
|
||||
|
||||
# EXTENSIONS PUBLICATION DIRECTORY
|
||||
public_dir: public
|
||||
|
||||
# STANDARD HOSTS EXTENSIONS LIST
|
||||
stdnotes_extensions_list: standardnotes-extensions-list.txt
|
||||
|
||||
14
extension.yaml.sample
Normal file
14
extension.yaml.sample
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
id: <tld.domain.organization.extension-name>
|
||||
github: <organization/repository>
|
||||
main: <index.html>
|
||||
|
||||
name: <Extension_Name>
|
||||
content_type: SN|Component
|
||||
area: editor-stack
|
||||
version: <0.0.1>
|
||||
marketing_url: <https://github.com/organization/extension>
|
||||
thumbnail_url: < https://raw.githubusercontent.com/organization/extension/master/thumbnail.png>
|
||||
description: <Description of extension>
|
||||
flags: []
|
||||
...
|
||||
14
extensions/append-editor.yaml
Normal file
14
extensions/append-editor.yaml
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
id: com.append-editor.beta
|
||||
github: TheodoreChu/append-editor
|
||||
main: public/index.html
|
||||
|
||||
name: Append Editor - Beta
|
||||
content_type: SN|Component
|
||||
area: editor-editor
|
||||
version: 1.2.6
|
||||
marketing_url: https://appendeditor.com
|
||||
thumbnail_url:
|
||||
description: Append to your notes.
|
||||
flags: []
|
||||
...
|
||||
14
extensions/code-editor-fold.yaml
Normal file
14
extensions/code-editor-fold.yaml
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
id: org.matt-anderson.code-editor-fold
|
||||
github: matta9001/code-editor-fold
|
||||
main: index.html
|
||||
|
||||
name: Code Editor Fold
|
||||
content_type: SN|Component
|
||||
area: editor-editor
|
||||
version: 1.0.0
|
||||
marketing_url: https://github.com/matta9001/code-editor-fold
|
||||
thumbnail_url: https://raw.githubusercontent.com/matta9001/code-editor-fold/main/code_editor_preview.png
|
||||
description: A fork of the official code editor which includes header and code folding.
|
||||
flags: []
|
||||
...
|
||||
@@ -1,15 +1,15 @@
|
||||
---
|
||||
id: com.github.dark-hybrid-theme-sn
|
||||
github: jakecza/dark-hybrid-theme-sn
|
||||
id: io.github.xthursdayx.dark-hybrid-theme-sn
|
||||
github: xthursdayx/dark-hybrid-theme-sn
|
||||
main: dist/dist.css
|
||||
|
||||
name: Dark Hybrid
|
||||
content_type: SN|Theme
|
||||
area: themes
|
||||
version: 1.1
|
||||
marketing_url: https://github.com/jakecza/dark-hybrid-theme-sn
|
||||
thumbnail_url: https://raw.githubusercontent.com/jakecza/dark-hybrid-theme-sn/master/preview.png
|
||||
description: Dark hybrid theme for Standard Notes.
|
||||
version: v1.2
|
||||
marketing_url: https://github.com/xthursdayx/dark-hybrid-theme-sn
|
||||
thumbnail_url: https://raw.githubusercontent.com/xthursdayx/dark-hybrid-theme-sn/master/preview.png
|
||||
description: Dark Hybrid Theme Extension for Standard Notes.
|
||||
|
||||
statusBar: dark-content
|
||||
dock_icon:
|
||||
|
||||
14
extensions/fast-editor.yaml
Normal file
14
extensions/fast-editor.yaml
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
id: dev.dec0dOS.fast_editor
|
||||
github: dec0dOS/standard-notes-fast-editor
|
||||
main: index.html
|
||||
|
||||
name: Fast Editor
|
||||
content_type: SN|Component
|
||||
area: editor-editor
|
||||
version: 4.0.2
|
||||
marketing_url: https://github.com/dec0dOS/standard-notes-fast-editor
|
||||
thumbnail_url:
|
||||
description: A mobile-friendly and high-performance editor that makes it easy to write and read nested notes.
|
||||
flags: []
|
||||
...
|
||||
19
extensions/grey-scale-theme.yaml
Normal file
19
extensions/grey-scale-theme.yaml
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
id: io.github.hkp2k.sn-theme-grey-scale
|
||||
github: hkp2k/sn-theme-grey-scale
|
||||
main: dist/dist.css
|
||||
|
||||
name: Grey Scale
|
||||
content_type: SN|Theme
|
||||
area: themes
|
||||
version: 1.0.16
|
||||
marketing_url: https://github.com/hkp2k/sn-theme-grey-scale
|
||||
description: Grey Scale theme for Standard Notes.
|
||||
|
||||
statusBar: grey-scale
|
||||
dock_icon:
|
||||
type: circle
|
||||
background_color: '#2f2f2f'
|
||||
foreground_color: '#404040'
|
||||
border_color: '#2f2f2f'
|
||||
...
|
||||
20
extensions/gruvbox-muted-theme-blue.yaml
Normal file
20
extensions/gruvbox-muted-theme-blue.yaml
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
id: io.github.xthursdayx.sn-gruvbox-muted-theme-blue
|
||||
github: xthursdayx/sn-gruvbox-muted-theme
|
||||
main: blue/dist/dist.css
|
||||
|
||||
name: Gruvbox Muted Theme Blue
|
||||
content_type: SN|Theme
|
||||
area: themes
|
||||
version: 0.0.1
|
||||
marketing_url: https://github.com/xthursdayx/sn-gruvbox-muted-theme/
|
||||
thumbnail_url: https://raw.githubusercontent.com/xthursdayx/sn-gruvbox-muted-theme/main/blue/blue-screenshot.png
|
||||
description: Gruvbox Blue Muted Theme for Standard Notes.
|
||||
|
||||
statusBar: dark-content
|
||||
dock_icon:
|
||||
type: circle
|
||||
background_color: '#458588'
|
||||
foreground_color: '#3c3836'
|
||||
border_color: '#458588'
|
||||
...
|
||||
14
extensions/indent-editor.yaml
Normal file
14
extensions/indent-editor.yaml
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
id: dev.maxlap.indent_editor
|
||||
github: MaxLap/standard-notes-indent-editor
|
||||
main: index.html
|
||||
|
||||
name: Indent Editor
|
||||
content_type: SN|Component
|
||||
area: editor-editor
|
||||
version: 1.6.0
|
||||
marketing_url: https://github.com/MaxLap/standard-notes-indent-editor
|
||||
thumbnail_url:
|
||||
description: A plain text editor with improved usability and readability.
|
||||
flags: []
|
||||
...
|
||||
19
extensions/macos-dark-theme.yaml
Normal file
19
extensions/macos-dark-theme.yaml
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
id: io.github.mjfakler.sn-macos-dark-theme
|
||||
github: mjfakler/sn-macos-dark-theme
|
||||
main: dist/dist.css
|
||||
|
||||
name: macOS Dark Theme
|
||||
content_type: SN|Theme
|
||||
area: themes
|
||||
version: 1.0.3
|
||||
marketing_url: https://github.com/mjfakler/sn-macos-dark-theme
|
||||
description: macOS Dark Mode theme for Standard Notes.
|
||||
|
||||
statusBar: dark-content
|
||||
dock_icon:
|
||||
type: circle
|
||||
background_color: '#3a3a3c'
|
||||
foreground_color: '#FAFBFF'
|
||||
border_color: '#2c2c2e'
|
||||
...
|
||||
20
extensions/monochrome-dark-theme.yaml
Normal file
20
extensions/monochrome-dark-theme.yaml
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
id: tech.gunderson.sn-theme-monochrome-dark
|
||||
github: Parkertg/sn-theme-monochrome-dark
|
||||
main: main.css
|
||||
|
||||
name: Monochrome Dark
|
||||
content_type: SN|Theme
|
||||
area: themes
|
||||
version: 1.2
|
||||
marketing_url: https://github.com/Parkertg/sn-theme-monochrome-dark
|
||||
thumbnail_url: https://raw.githubusercontent.com/Parkertg/sn-theme-monochrome-dark/main/preview.png
|
||||
description: A near-monochrome dark theme for Standard Notes.
|
||||
|
||||
statusBar: dark-content
|
||||
dock_icon:
|
||||
type: circle
|
||||
background_color: '#adadad'
|
||||
foreground_color: '#ffffff'
|
||||
border_color: '#ffffff'
|
||||
...
|
||||
@@ -1,20 +1,20 @@
|
||||
---
|
||||
id: io.github.lzambarda.sn-nord-theme
|
||||
github: lzambarda/sn-nord-theme
|
||||
main: theme.css
|
||||
id: io.github.xthursdayx.sn-nord-theme
|
||||
github: xthursdayx/sn-nord-theme
|
||||
main: dist/dist.css
|
||||
|
||||
name: Nord Theme
|
||||
content_type: SN|Theme
|
||||
area: themes
|
||||
version: 0.0.2
|
||||
marketing_url: https://github.com/lzambarda/sn-nord-theme
|
||||
version: 1.0.1
|
||||
marketing_url: https://github.com/xthursdayx/sn-nord-theme
|
||||
thumbnail_url: https://raw.githubusercontent.com/lzambarda/sn-nord-theme/master/preview.png
|
||||
description: Standard Notes theme inspired by the magnificent Nord Theme.
|
||||
description: An arctic, north-bluish clean and elegant Standard Notes theme.
|
||||
|
||||
statusBar: dark-content
|
||||
dock_icon:
|
||||
type: circle
|
||||
background_color: '#5e81ac'
|
||||
foreground_color: '#eceff4'
|
||||
border_color: '#5e81ac'
|
||||
background_color: '#88C0D0'
|
||||
foreground_color: '#88C0D0'
|
||||
border_color: '#88C0D0'
|
||||
...
|
||||
|
||||
14
extensions/scratch-editor.yaml
Normal file
14
extensions/scratch-editor.yaml
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
id: com.dylanonelson.sn-scratch-editor
|
||||
github: dylanonelson/sn-scratch-editor
|
||||
main: dist/index.html
|
||||
|
||||
name: Scratch Editor
|
||||
content_type: SN|Component
|
||||
area: editor-editor
|
||||
version: 0.0.41
|
||||
marketing_url: https://dylanonelson.github.io/sn-scratch-editor
|
||||
thumbnail_url:
|
||||
description: An editor for writing things down.
|
||||
flags: []
|
||||
...
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
id: space.yuggoth.sn-slate-theme
|
||||
github: yithian/slate-theme/
|
||||
main: dist/standard-notes.css
|
||||
github: yithian/slate-theme
|
||||
main: dist/dist.css
|
||||
|
||||
name: Slate
|
||||
content_type: SN|Theme
|
||||
|
||||
20
extensions/subtle-dark-theme.yaml
Normal file
20
extensions/subtle-dark-theme.yaml
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
id: tech.gunderson.sn-theme-subtle-dark
|
||||
github: Parkertg/sn-theme-subtle-dark
|
||||
main: dist/dist.css
|
||||
|
||||
name: Subtle Dark
|
||||
content_type: SN|Theme
|
||||
area: themes
|
||||
version: 1.1
|
||||
marketing_url: https://github.com/Parkertg/sn-theme-subtle-dark
|
||||
thumbnail_url: https://raw.githubusercontent.com/Parkertg/sn-theme-subtle-dark/main/preview.png
|
||||
description: A low saturation orangish dark theme for Standard Notes.
|
||||
|
||||
statusBar: dark-content
|
||||
dock_icon:
|
||||
type: circle
|
||||
background_color: '#897860'
|
||||
foreground_color: '#c9d5d5'
|
||||
border_color: '#897860'
|
||||
...
|
||||
19
extensions/subtle-light-theme.yaml
Normal file
19
extensions/subtle-light-theme.yaml
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
id: tech.gunderson.sn-theme-subtle-light
|
||||
github: Parkertg/sn-theme-subtle-light
|
||||
main: dist/dist.css
|
||||
|
||||
name: Subtle Light
|
||||
content_type: SN|Theme
|
||||
area: themes
|
||||
version: 1.0
|
||||
marketing_url: https://github.com/Parkertg/sn-theme-subtle-light
|
||||
thumbnail_url: https://raw.githubusercontent.com/Parkertg/sn-theme-subtle-light/main/preview.png
|
||||
description: A lower saturation/contrast light theme for Standard Notes.
|
||||
|
||||
dock_icon:
|
||||
type: circle
|
||||
background_color: '#edddc4'
|
||||
foreground_color: '#ffffff'
|
||||
border_color: '#ffffff'
|
||||
...
|
||||
14
extensions/ultimate-editor.yaml
Normal file
14
extensions/ultimate-editor.yaml
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
id: dev.dec0dOS.ultimate_editor
|
||||
github: dec0dOS/standard-notes-ultimate-editor
|
||||
main: public/index.html
|
||||
|
||||
name: Ultimate Editor
|
||||
content_type: SN|Component
|
||||
area: editor-editor
|
||||
version: 2.7.2
|
||||
marketing_url: https://github.com/dec0dOS/standard-notes-ultimate-editor
|
||||
thumbnail_url:
|
||||
description: Markdown editor with improved mobile support and performance.
|
||||
flags: []
|
||||
...
|
||||
28
standardnotes-extensions-list.txt
Normal file
28
standardnotes-extensions-list.txt
Normal file
@@ -0,0 +1,28 @@
|
||||
#############################################################################
|
||||
# List of standard notes's extensions who's identifier need to be modified to
|
||||
# get around the issue: https://github.com/standardnotes/desktop/issues/789
|
||||
#############################################################################
|
||||
action-bar.yaml
|
||||
autobiography-theme.yaml
|
||||
autocomplete-tags.yaml
|
||||
bold-editor.yaml
|
||||
code-editor.yaml
|
||||
dynamic-theme.yaml
|
||||
focus-theme.yaml
|
||||
folders-component.yaml
|
||||
futura-theme.yaml
|
||||
github-push.yaml
|
||||
markdown-basic.yaml
|
||||
markdown-pro-editor.yaml
|
||||
math-editor.yaml
|
||||
mfa-link.yaml
|
||||
midnight-theme.yaml
|
||||
minimal-markdown-editor.yaml
|
||||
no-distraction-theme.yaml
|
||||
plus-editor.yaml
|
||||
secure-spreadsheets.yaml
|
||||
simple-task-editor.yaml
|
||||
solarized-dark-theme.yaml
|
||||
titanium-theme.yaml
|
||||
token-vault.yaml
|
||||
vim-editor.yaml
|
||||
20
theme.yaml.sample
Normal file
20
theme.yaml.sample
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
id: <tld.domain.organization.theme-name>
|
||||
github: <organization/repository>
|
||||
main: <dist/dist.css>
|
||||
|
||||
name: <Theme_Name>
|
||||
content_type: SN|Theme
|
||||
area: themes
|
||||
version: <0.0.1>
|
||||
marketing_url: <https://github.com/organization/theme>
|
||||
thumbnail_url: <https://raw.githubusercontent.com/organization/theme/master/thumbnail.png>
|
||||
description: <Description of theme>
|
||||
|
||||
statusBar: dark-content
|
||||
dock_icon:
|
||||
type: circle
|
||||
background_color: '#726a7b' #your chosen icon background color
|
||||
foreground_color: '#ffffff' #your chosen icon foreground color
|
||||
border_color: '#726a7b' #your chosen icon border color
|
||||
...
|
||||
Reference in New Issue
Block a user