Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
b76c0e4
Merge pull request #32 from RT-coding-team/develop
derekmaxson Mar 19, 2022
5f327e9
Merge pull request #35 from RT-coding-team/develop
derekmaxson Mar 21, 2022
cb0f78f
Merge pull request #37 from RT-coding-team/develop
derekmaxson Apr 1, 2022
ea4b7af
Merge pull request #38 from RT-coding-team/develop
derekmaxson Apr 21, 2022
13bfd16
Merge pull request #41 from RT-coding-team/develop
derekmaxson Apr 26, 2022
dafebbb
Merge pull request #42 from RT-coding-team/develop
derekmaxson Apr 27, 2022
876c8e9
Merge pull request #43 from RT-coding-team/develop
derekmaxson May 9, 2022
cd932b7
Merge pull request #44 from RT-coding-team/develop
derekmaxson May 9, 2022
228fc8f
Merge pull request #47 from RT-coding-team/develop
derekmaxson May 12, 2022
52ea316
Merge pull request #48 from RT-coding-team/develop
derekmaxson May 13, 2022
23ff5b7
Merge pull request #50 from RT-coding-team/develop
codemis May 26, 2022
19acecf
Merge pull request #51 from RT-coding-team/develop
derekmaxson May 26, 2022
493e237
Merge pull request #52 from RT-coding-team/develop
derekmaxson Jun 9, 2022
2289767
Merge pull request #53 from RT-coding-team/develop
derekmaxson Jun 9, 2022
e4e0db0
Merge pull request #54 from RT-coding-team/develop
derekmaxson Jun 18, 2022
1d9451e
Merge pull request #55 from RT-coding-team/develop
derekmaxson Jul 25, 2022
09459a1
Created a component for handling the download of media, and added a l…
Aug 10, 2022
a094e0d
We no longer create a blob for the file due to browser size limits. …
Aug 10, 2022
3be957f
Removed unused dependency.
Aug 10, 2022
cdfca4f
We are now using the new download button component in all the viewers.
Aug 10, 2022
66b56e0
Removed unused provider.
Aug 10, 2022
e4dad36
Merge pull request #56 from RT-coding-team/download-progress
codemis Aug 17, 2022
83e188f
Initial commit
kirkdwilson Nov 23, 2022
805b530
Initial commit
kirkdwilson Nov 23, 2022
317bdf8
Merge branch 'main' of https://github.com/ConnectBox/mediainterface2
kirkdwilson Nov 23, 2022
fcc19aa
Add missing files
DorJamJr Nov 23, 2022
ce6d86b
Added latest Release
kirkdwilson Nov 23, 2022
9f6e14b
Merge branch 'main' of https://github.com/ConnectBox/mediainterface
kirkdwilson Nov 23, 2022
b1df477
Removed the releases folder
kirkdwilson Nov 24, 2022
fa7b8f5
Changed the media languageCodes.json
kirkdwilson Dec 15, 2022
a58ed3b
Added missing language codes
kirkdwilson Dec 15, 2022
6afc299
Merge pull request #1 from ConnectBox/main
derekmaxson Dec 22, 2022
887f83b
Change varable twoLetterCode to code
derekmaxson Dec 22, 2022
4bb9366
Just to kick off workflow
derekmaxson Dec 22, 2022
ae00dfe
Merge pull request #2 from ConnectBox/dev
derekmaxson Dec 22, 2022
0d85d84
Fix symlink
derekmaxson Dec 22, 2022
c4690fa
Update comment
derekmaxson Dec 22, 2022
322c07c
Kick the workflow
derekmaxson Dec 22, 2022
ce5e40c
Support for 3 letter language codes
derekmaxson Dec 22, 2022
a1e8508
Merge pull request #3 from ConnectBox/develop
derekmaxson Dec 22, 2022
96b7086
Add some debug logging
derekmaxson Dec 22, 2022
66494e5
Update language.ts
derekmaxson Dec 22, 2022
e21f0b4
Merge pull request #4 from RT-coding-team/develop
kirkdwilson Dec 22, 2022
2424c15
Corrected issues of link following, empty root directory other than l…
kirkdwilson Dec 22, 2022
745f175
Incremental Update: Handles tall file structures, symlinks
derekmaxson Dec 29, 2022
f8e920c
Adding cmn Mandarin
derekmaxson Dec 31, 2022
012d19d
Revert "Adding cmn Mandarin"
derekmaxson Dec 31, 2022
6d7183f
Add cmn Mandarin
derekmaxson Dec 31, 2022
fe8bedd
Changes for Scroll multi-directory interface
kirkdwilson Jan 1, 2023
edceef6
Merge branch 'main' of https://github.com/ConnectBox/mediainterface
kirkdwilson Jan 1, 2023
9e09de3
Handle webpath better: make index.html, skip images and other html files
derekmaxson Jan 1, 2023
53ce7a1
3 letter language test
derekmaxson Jan 1, 2023
caa4f9a
Merge branch 'main' into develop
derekmaxson Jan 1, 2023
0f52323
Update languageCodes.json
kirkdwilson Jan 1, 2023
af3a02a
Removed Well logo for Connectbox Logo
kirkdwilson May 6, 2023
b75b66e
Fix for web folders with spaces in the path
derekmaxson May 8, 2023
44d3af4
Fix empty config file
derekmaxson May 8, 2023
33ce19e
Look for languageCodes at beginning of thisDirectory before the -
derekmaxson May 9, 2023
20a53ef
Filename change
derekmaxson May 17, 2023
340699c
Namechange final
derekmaxson May 17, 2023
739ab8e
Documentation updates
derekmaxson May 17, 2023
1f1c189
Set zip variants as zips
derekmaxson Jun 4, 2023
8a0d88b
Don't show icon if no icon
derekmaxson Jun 4, 2023
e51340a
Episodes default to blank.gif when no thumbnail
derekmaxson Jun 5, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/dev-release.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Build the Application
name: Build the Dev Application
on:
push:
branches:
Expand Down
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2022 ConnectBox

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[![AppVersion-version](https://img.shields.io/badge/AppVersion-0.0.1-brightgreen.svg?style=flat)](https://github.com/delvedor/appversion?#version)

A multimedia interface designed for offline media boxes like the Connect Box.
A multimedia interface designed for offline media boxes like the Connect Box. There are at least two ways to populate the interface with content: (1) through packages created from [MediaBuilder](https://github.com/ConnectBox/mediabuilder) loaded from lazyLoader (see below) or (2) from semi-structured content located at /media/usb0/content which is typically on a USB drive attached to the device [Instructions](./mmiLoader.md).

## Usage

Expand Down
139 changes: 139 additions & 0 deletions main/lazyLoader.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
#!/usr/bin/python3
# Loads content from USB and creates the JSON / file structure for enhanced media interface


print ("lazyLoader: Starting...")

import json
import os
import pathlib
import sys
import time
from urllib.parse import unquote

# Defaults for Connectbox / TheWell
contentDirectory = "/var/www/enhanced/content/www/assets/content/"

failedItemCount = 0;

# URL:
url = ''
try:
if (sys.argv[1] and len(sys.argv[1]) > 0):
url = sys.argv[1];
print ("Download URL: " + url);
except:
print ("Download URL: NONE")

# See if we have a package subscription
isSubscribed = False;
try:
print ("Check For Subscription");
f = open('/usr/local/connectbox/brand.txt');
brand = json.load(f)
f = open(contentDirectory + 'subscription.json');
subscription = json.load(f)
# IF we don't have argument of new URL AND we have subscription data, this is a subscribed box
if (len(url) == 0 and 'packagesAPIFeed' in subscription):
isSubscribed = True;
subscription['packageName'] = unquote(subscription['packagesAPIFeed']).split("packageName=")[1];
print('Box is subscribed to: ' + subscription['packageName'])
except FileNotFoundError:
print("This device is not subscribed to Server package");

# If subscribed, let's check for updates
if (isSubscribed):
print ("Getting packagesAPIFeed From " + subscription['packagesAPIFeed'])
os.system("wget -nv '" + subscription['packagesAPIFeed'] + "' -O /tmp/packages.json")
f = open('/tmp/packages.json');
packages = json.load(f);
for record in packages:
#print ("Subscripton: Is this a match? " + record['package']);
if (record['is_slim'] is True and record['package'] == subscription['packageName']):
print ("Subscription: " + record["package"]);
if (subscription['lastUpdated'] < record['timestamp']):
print ("Subscription: Updates Found");
url = record['filepath']
subscription['lastUpdated'] = time.time();
with open(contentDirectory + 'subscription.json', 'w', encoding='utf-8') as f:
json.dump(subscription, f, ensure_ascii=False, indent=4)
else:
print ("Subscription: No Updates Found");

# First Download the URL and unzip it or find missing content
if (len(url) > 1):
print ("Handling File: " + url)
os.system("wget -nv '" + url + "' -O /tmp/openwell.zip")
os.system("unzip -o /tmp/openwell.zip -d /var/www/enhanced/content/www/assets/")
print ("Loaded Package File")
else:
print ("No Package File To Download");

print ("==================================================")
print ("Looking for missing content and trying to download")

directories = ["data", "images", "media", "html"]

# Go through all the language folders in the package
for language in next(os.walk(contentDirectory))[1]:
print ("Found Possible Language Folder: " + language)
if os.path.exists(contentDirectory + language + "/data/main.json"):
print ("Confirmed Language: " + language + " main.json exists")
# Load main.json to process
f = open (contentDirectory + language + "/data/main.json")
thisMain = json.load(f)
for directory in directories:
if os.path.isdir(contentDirectory + language + "/" + directory):
print (" Directory Exists: " + contentDirectory + language + "/" + directory)
else:
try:
os.mkdir(contentDirectory + language + "/" + directory)
print (" Created Directory at " + contentDirectory + language + "/" + directory)
except:
print (" FAILED to Create Directory at " + contentDirectory + language + "/" + directory)
print (" ")
print ("=================================================================================")
for content in thisMain["content"]:
print (" Processing: " + content["title"])
f = open (contentDirectory + language + "/data/" + content["slug"] + ".json")
details = json.load(f)
#print (json.dumps(details))
items = []
try:
items = details["episodes"]
os.system("wget -nv '" + details["imageUrl"] + "' -O " + contentDirectory + language + "/images/" + details["image"])
print (" Loading Multi-Episodic Content: " + details["title"] )
except:
items = [details]
print (" Single Episodic Content: " + details["title"])
#print (json.dumps(items))
for item in items:
print (" Checking Media Content: " + item["filename"])
if (os.path.exists(contentDirectory + language + "/media/" + item["filename"])):
print (" Content Exists: " + item["filename"])
else:
try:
print (" LOAD CONTENT: " + item["filename"] + " from " + item["resourceUrl"])
os.system("wget -nv '" + item["resourceUrl"] + "' -O " + contentDirectory + language + "/media/" + item["filename"])
print (" Content Downloaded to: " + item["filename"])
except:
print (" FAILED To Download: " + item["title"])
failedItemCount+=1;
print ("----------------------------------------")
print (" ")
print (" Checking Image Content: " + item["image"])
if (os.path.exists(contentDirectory + language + "/images/" + item["image"])):
print (" Content Exists: " + item["image"])
else:
try:
print (" LOAD CONTENT: " + item["image"] + " from " + item["imageUrl"])
os.system("wget -nv '" + item["imageUrl"] + "' -O " + contentDirectory + language + "/images/" + item["image"])
print (" Content Downloaded to: " + item["image"])
except:
print (" FAILED To Download: " + item["title"])
failedItemCount+=1;
print ("----------------------------------------")
print (" ")

print ("Failed Item Count:" + str(failedItemCount));
print ("Done.")
2 changes: 1 addition & 1 deletion mmiloader.py → main/mmiloader.py
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -418,4 +418,4 @@ def intersection(lst1, lst2):

print ("Copying Metadata to Zip File On USB");
os.system ("(cd " + contentDirectory + " && zip --symlinks -r " + zipFileName + " *)");
print ("DONE");
print ("DONE");
Binary file added mediainterface - Shortcut.lnk
Binary file not shown.
97 changes: 97 additions & 0 deletions mmiLoader.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Loading Content from USB with mmiLoader.py

## File Structure on USB:
Because the MMI primarily displays content as a flat list of items, it is best to
```
/media/usb0/content
├── en
│ ├── Audio File Name and Source.mp3
│ ├── Audio Bible.mp3
│ ├── Video Title.mp4
│ ├── Jesus Film.mp4
│ ├── Descriptive-Name-For-Document.pdf
├── es
│ ├── Audio Bible.mp3
│ ├── Jesus Film.mp4
│ ├── Web Based Set of Commentaries
│ │ ├── index.html (A web folder is known only because of index.html)
│ │ ├── images
│ │ ├── ...
│ │ ├── ...
├── ar
│ ├── Arabic Bible.epub
│ ├── Jesus Film.mp4
│ ├── Audio Bible
│ │ ├── 01-Genesis.mp3
│ │ ├── 02-Exodus.mp3
│ │ ├── 03-Leviticus.mp3
│ │ ├── 04-Numbers.mp3
├── tl (Not Recommended Structure)
│ ├── Audio Bible
│ │ ├── Genesis.mp3
│ │ ├── Exodus.mp3
│ │ ├── Leviticus.mp3
│ │ ├── Numbers.mp3
├── tl (Recommended Structure)
│ ├── Audio Bible
│ │ ├── 01-Genesis.mp3
│ │ ├── 02-Exodus.mp3
│ │ ├── 03-Leviticus.mp3
│ │ ├── 04-Numbers.mp3
├── amk (Not Recommended Structure)
│ ├── Commentaries
│ │ ├── Commentary Set 1
│ │ │ ├── 01-Genesis.epub
│ │ │ ├── 02-Exodus.epub
│ │ │ ├── 03-Leviticus.epub
│ │ │ ├── 04-Numbers.epub
│ │ ├── Commentary Set 2
│ │ │ ├── 01-Genesis.epub
│ │ │ ├── 02-Exodus.epub
│ │ │ ├── 03-Leviticus.epub
│ │ │ ├── 04-Numbers.epub
│ │ ├── Commentary Set 3
│ │ │ ├── 01-Genesis.epub
│ │ │ ├── 02-Exodus.epub
│ │ │ ├── 03-Leviticus.epub
│ │ │ ├── 04-Numbers.epub
├── amk (Recommended Structure)
│ ├── Commentary Set 1
│ │ ├── 01-Genesis.epub
│ │ ├── 02-Exodus.epub
│ │ ├── 03-Leviticus.epub
│ │ ├── 04-Numbers.epub
│ ├── Commentary Set 2
│ │ ├── 01-Genesis.epub
│ │ ├── 02-Exodus.epub
│ │ ├── 03-Leviticus.epub
│ │ ├── 04-Numbers.epub
│ ├── Commentary Set 3
│ │ ├── 01-Genesis.epub
│ │ ├── 02-Exodus.epub
│ │ ├── 03-Leviticus.epub
│ │ ├── 04-Numbers.epub
```
#### Notes:
* Supported file types are listed [here](src/assets/templates/en/data/types.json)
* Best practice is to have language codes (2 or 3 letter -- [see list](src/assets/templates/languageCodes.json)) at the root level above `/media/usb0/content`. If the directory name, matches a language code, or if the portion of the directory name prior to a <space> or a <dash> matches a language code, then the directory will be processed as a language.
* In example above, all are valid examples but not all preferred.
* In language en, each of the 5 files are treated as peer elements and will each be listed on the interface main page.
* In language es, there will be 3 items on the interface main page: the Bible, the film and the web site.
* In language tl, the Not Recommended structure will not correctly order the books of the Bible due to alphabetical ordering. The Recommended structure using leading zeroes will put the books in the correct order.
* In language ar, there will be 3 items on the interface main page: the Bible, the film and the Audio Bible. The difference is that the Audio Bible is set up as a collection, where each of the books of the Bible will be listed on a subpage, once the Audio Bible collection is clicked. It is advantageous to use numbers with leading zeroes to have them be in alphabetical order.
* In language amk (Not Recommended), there will be just 1 item on the interface main page: a collection called Commentaries. Inside will be a confusing mess because all of the files in the Commentaries collection will be mixed. Thus, multiple levels of subfolders should be avoided.
* In language amk (Recommended), there will be 3 collections on the interface main page with each collection's epub books listed within.

## Web Directories
* Using web directories of existing web site content is a keen way to deliver web Content
* Because the Connectbox may not be always connected to the Internet, care should be used to ensure that no external libraries (Javascript, CSS, fonts) are required by the content.
* The main page of the web content should always be index.html
* Other files in web directories or sub directories will not be indexed other than as a part of the web directory.

## Video Thumbnails
The system will automatically generate thumbnails for the the videos. This can take some time when indexing larger folder structures with many videos.

## Usage:
* Graphical Admin: After logging in to Connectbox's Admin Web Interface (Typically http://connectbox/admin), click on the button labeled: Load Content From USB Flash (/USB/package or /USB/content)
* Shell: As root, you can execute `/usr/local/connectbox/bin/mmiLoader.py`. To fully execute with re-indexing, also remove the file `/media/usb0/content/saved.zip` This will permit you to view all the logs in real time.
Loading