Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementation home screen layout #4599

Draft
wants to merge 5 commits into
base: 14-dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
40 changes: 40 additions & 0 deletions flowerpot/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# The `flowerpot` ruleset format

> Keeping beautiful things organized.

## Basic overview

We want to be able to provide an automatic categorization of apps into folders and tabs and needed a fitting file format for storing rules in a compact but human-readable way. This is what flowerpot is, a simple format for rule lists which is easy to read and equally easy to parse from code. Repurposing the general ideas of this format for other uses is also easily possible.

## Format

Flowerpot files are built as a line delimited list of rules. Except for metadata related rules/tags, most rules are filters. The parser identifies rules by the leading character.

### Supported rules

| Identifier | Rule | Description | Notes |
|:----------:|------------------|-------------------------------------|---------------------------------------------------------|
| | Package | Package name filter | Version 1 only supports full package names as filter |
| `#` | Comment | Comment | |
| `$` | Version | Version tag (integer) | Must be the first non-comment item, can only occur once |
| `:` | IntentAction | Intent action to filter by | |
| `;` | IntentCategory | Intent category to filter by | Tested in combination with the `MAIN` action |
| `&` | CodeRule | Rule which has been defined in code | Accepts arguments seperated by `|` |

### File names

Each file is a ruleset for one category, and the name of the file represents the name (codename) of that category. Flowerpot files have no file extension. You are advised to use uppercase (snake case) filenames spelling out the English name of the category.

### Versioning

Versions are identified by an incrementing integer value and accompanied by codenames. Codenames are given alphabetically and should be the name of a flower (I encourage everyone to use names of pink flowers, if possible).

#### Current Version

The format is currently at version 1 (`azalea`). This is the initial version of flowerpot.

> Azalea - A beautiful pink flower, known in China as "thinking of home bush" (sixiang shu).

#### Past versions

There are no past versions of flowerpot yet.
29 changes: 29 additions & 0 deletions flowerpot/lawnchair_specifics.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
## Categories

```python
{
"HEALTH_AND_FITNESS": ["HEALTH_AND_FITNESS", "MEDICAL"],
"KNOWLEDGE_AND_REFERENCE": ["EDUCATION", "BOOKS_AND_REFERENCE", "WEATHER"],
"NEWS": ["NEWS_AND_MAGAZINES"],
"ENTERTAINMENT": ["ENTERTAINMENT", "MUSIC_AND_AUDIO", "VIDEO_PLAYERS"],
"MUSIC": ["MUSIC_AND_AUDIO"],
"LIFESTYLE": ["LIFESTYLE", "BEAUTY"],
"PHOTOGRAPHY": ["PHOTOGRAPHY"],
"BUSINESS_AND_PRODUCTIVITY": ["PRODUCTIVITY", "BUSINESS"],
"TOOLS": ["TOOLS"],
"FINANCE": ["FINANCE"],
"COMMUNICATION": ["COMMUNCICATION"],
"SOCIAL": ["SOCIAL"],
"TRAVEL_AND_NAVIGATION": ["MAPS_AND_NAVIGATION", "TRAVEL_AND_LOCAL"],
"GAME": ["GAME"], # Actually identified by isGame manifest tag
"FOOD_AND_DRINK": ["FOOD_AND_DRINK"],
"PERSONALIZATION": ["PERSONALIZATION"], # Additionally identify icon packs by manifest
"SHOPPING": ["SHOPPING"]
}
```

The base package name lists are built by scraping the Play Store using `playstore.py`, these lists are then merged into our categories using `merge.py`, together with static template files for base rules.

## Manually adding a rule

If you want to manually add a rule to one of Lawnchair's rulesets you can simply add it to one of the static templates in the `templates/` directory. Create one with a categories name if none exists yet.
69 changes: 69 additions & 0 deletions flowerpot/merge.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# This file is part of Lawnchair Launcher.
#
# Lawnchair Launcher 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.
#
# Lawnchair Launcher 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 Lawnchair Launcher. If not, see <https://www.gnu.org/licenses/>.

from pathlib import Path
import shutil
import time
import sys

CATEGORY_MAP = {
"HEALTH_AND_FITNESS": ["HEALTH_AND_FITNESS", "MEDICAL"],
"KNOWLEDGE_AND_REFERENCE": ["EDUCATION", "BOOKS_AND_REFERENCE", "WEATHER"],
"NEWS": ["NEWS_AND_MAGAZINES"],
"ENTERTAINMENT": ["ENTERTAINMENT", "MUSIC_AND_AUDIO", "VIDEO_PLAYERS", "MUSIC_AND_AUDIO"],
"MUSIC": ["MUSIC_AND_AUDIO"],
"LIFESTYLE": ["LIFESTYLE", "BEAUTY", "SHOPPING"],
"PHOTOGRAPHY": ["PHOTOGRAPHY"],
"BUSINESS_AND_PRODUCTIVITY": ["PRODUCTIVITY", "BUSINESS", "FINANCE"],
"TOOLS": ["TOOLS", "VIDEO_PLAYERS"],
"COMMUNICATION": ["COMMUNICATION", "SOCIAL"],
"TRAVEL_AND_NAVIGATION": ["MAPS_AND_NAVIGATION", "TRAVEL_AND_LOCAL"],
"GAME": ["GAME"], # Actually identified by isGame manifest tag which not all apps have :(
"FOOD_AND_DRINK": ["FOOD_AND_DRINK"],
"PERSONALIZATION": ["PERSONALIZATION"] # Additionally identify icon packs by manifest
}

IN_PATH = "playstore"
OUT_PATH = "../lawnchair/assets/flowerpot/"
TEMPLATE_PATH = "templates"
FORMAT_VERSION = "1"
FORMAT_VERSION_HUMAN = "azalea"

out_p = Path(OUT_PATH)
if out_p.exists():
shutil.rmtree(out_p)

try:
out_p.mkdir()
except OSError:
print ("Creation of the directory %s failed" % OUT_PATH)

for category in CATEGORY_MAP.keys():
with open("%s/%s" % (OUT_PATH, category), "a+") as out:
out.write("# generated at %s using %s\n" % (time.ctime(), sys.argv[0]))
out.write("# format: flowerpot-%s (%s)\n" % (FORMAT_VERSION, FORMAT_VERSION_HUMAN))
out.write("# specs: https://del.dog/flowerpot\n")
out.write("$%s\n" % FORMAT_VERSION)
template = Path("%s/%s" % (TEMPLATE_PATH, category))
if template.exists():
out.write("# STATIC TEMPLATE\n")
out.write(template.read_text())
for origin in CATEGORY_MAP[category]:
input = Path("%s/%s" % (IN_PATH, origin))
if input.exists():
out.write("# %s\n" % origin)
out.write(input.read_text())
else:
print("No input file found for %s" % origin)
Loading