mirror of https://github.com/mvdan/fdroidcl.git
6 changed files with 268 additions and 200 deletions
@ -0,0 +1,66 @@
|
||||
/* Copyright (c) 2015, Daniel Martí <mvdan@mvdan.cc> */ |
||||
/* See LICENSE for licensing information */ |
||||
|
||||
package main |
||||
|
||||
import ( |
||||
"log" |
||||
|
||||
"github.com/mvdan/fdroidcl" |
||||
"github.com/mvdan/fdroidcl/adb" |
||||
) |
||||
|
||||
var cmdInstalled = &Command{ |
||||
Name: "installed", |
||||
Short: "List installed apps", |
||||
} |
||||
|
||||
func init() { |
||||
cmdInstalled.Run = runInstalled |
||||
} |
||||
|
||||
func runInstalled(args []string) { |
||||
index := mustLoadIndex() |
||||
startAdbIfNeeded() |
||||
device := oneDevice() |
||||
installed := mustInstalled(device) |
||||
apps := filterAppsInstalled(index.Apps, installed) |
||||
printApps(apps) |
||||
} |
||||
|
||||
func oneDevice() adb.Device { |
||||
devices, err := adb.Devices() |
||||
if err != nil { |
||||
log.Fatalf("Could not get devices: %v", err) |
||||
} |
||||
if len(devices) == 0 { |
||||
log.Fatalf("No devices found") |
||||
} |
||||
if len(devices) > 1 { |
||||
log.Fatalf("Too many devices found") |
||||
} |
||||
return devices[0] |
||||
} |
||||
|
||||
func mustInstalled(device adb.Device) []string { |
||||
installed, err := device.Installed() |
||||
if err != nil { |
||||
log.Fatalf("Could not get installed packages: %v", err) |
||||
} |
||||
return installed |
||||
} |
||||
|
||||
func filterAppsInstalled(apps []fdroidcl.App, installed []string) []fdroidcl.App { |
||||
instMap := make(map[string]struct{}, len(installed)) |
||||
for _, id := range installed { |
||||
instMap[id] = struct{}{} |
||||
} |
||||
var result []fdroidcl.App |
||||
for _, app := range apps { |
||||
if _, e := instMap[app.ID]; !e { |
||||
continue |
||||
} |
||||
result = append(result, app) |
||||
} |
||||
return result |
||||
} |
||||
@ -0,0 +1,58 @@
|
||||
/* Copyright (c) 2015, Daniel Martí <mvdan@mvdan.cc> */ |
||||
/* See LICENSE for licensing information */ |
||||
|
||||
package main |
||||
|
||||
import ( |
||||
"strings" |
||||
|
||||
"github.com/mvdan/fdroidcl" |
||||
) |
||||
|
||||
var cmdSearch = &Command{ |
||||
Name: "search", |
||||
Short: "Search available apps", |
||||
} |
||||
|
||||
func init() { |
||||
cmdSearch.Run = runSearch |
||||
} |
||||
|
||||
func runSearch(args []string) { |
||||
index := mustLoadIndex() |
||||
apps := filterAppsSearch(index.Apps, args) |
||||
printApps(apps) |
||||
} |
||||
|
||||
func filterAppsSearch(apps []fdroidcl.App, terms []string) []fdroidcl.App { |
||||
for _, term := range terms { |
||||
term = strings.ToLower(term) |
||||
} |
||||
var result []fdroidcl.App |
||||
for _, app := range apps { |
||||
fields := []string{ |
||||
strings.ToLower(app.ID), |
||||
strings.ToLower(app.Name), |
||||
strings.ToLower(app.Summary), |
||||
strings.ToLower(app.Desc), |
||||
} |
||||
if !appMatches(fields, terms) { |
||||
continue |
||||
} |
||||
result = append(result, app) |
||||
} |
||||
return result |
||||
} |
||||
|
||||
func appMatches(fields []string, terms []string) bool { |
||||
fieldLoop: |
||||
for _, field := range fields { |
||||
for _, term := range terms { |
||||
if !strings.Contains(field, term) { |
||||
continue fieldLoop |
||||
} |
||||
} |
||||
return true |
||||
} |
||||
return false |
||||
} |
||||
@ -0,0 +1,112 @@
|
||||
/* Copyright (c) 2015, Daniel Martí <mvdan@mvdan.cc> */ |
||||
/* See LICENSE for licensing information */ |
||||
|
||||
package main |
||||
|
||||
import ( |
||||
"fmt" |
||||
"log" |
||||
"os" |
||||
"strings" |
||||
|
||||
"github.com/mvdan/fdroidcl" |
||||
) |
||||
|
||||
var cmdShow = &Command{ |
||||
Name: "show", |
||||
Short: "Show detailed info of an app", |
||||
} |
||||
|
||||
func init() { |
||||
cmdShow.Run = runShow |
||||
} |
||||
|
||||
func runShow(args []string) { |
||||
index := mustLoadIndex() |
||||
found := make(map[string]*fdroidcl.App, len(args)) |
||||
for _, appID := range args { |
||||
found[appID] = nil |
||||
} |
||||
for i := range index.Apps { |
||||
app := &index.Apps[i] |
||||
_, e := found[app.ID] |
||||
if !e { |
||||
continue |
||||
} |
||||
found[app.ID] = app |
||||
} |
||||
for i, appID := range args { |
||||
app, _ := found[appID] |
||||
if app == nil { |
||||
log.Fatalf("Could not find app with ID '%s'", appID) |
||||
} |
||||
if i > 0 { |
||||
fmt.Printf("\n--\n\n") |
||||
} |
||||
printAppDetailed(*app) |
||||
} |
||||
} |
||||
|
||||
func printAppDetailed(app fdroidcl.App) { |
||||
p := func(title string, format string, args ...interface{}) { |
||||
if format == "" { |
||||
fmt.Println(title) |
||||
} else { |
||||
fmt.Printf("%s %s\n", title, fmt.Sprintf(format, args...)) |
||||
} |
||||
} |
||||
p("Package :", "%s", app.ID) |
||||
p("Name :", "%s", app.Name) |
||||
p("Summary :", "%s", app.Summary) |
||||
p("Current Version :", "%s (%d)", app.CurApk.VName, app.CurApk.VCode) |
||||
p("Upstream Version :", "%s (%d)", app.CVName, app.CVCode) |
||||
p("License :", "%s", app.License) |
||||
if app.Categs != nil { |
||||
p("Categories :", "%s", strings.Join(app.Categs, ", ")) |
||||
} |
||||
if app.Website != "" { |
||||
p("Website :", "%s", app.Website) |
||||
} |
||||
if app.Source != "" { |
||||
p("Source :", "%s", app.Source) |
||||
} |
||||
if app.Tracker != "" { |
||||
p("Tracker :", "%s", app.Tracker) |
||||
} |
||||
if app.Changelog != "" { |
||||
p("Changelog :", "%s", app.Changelog) |
||||
} |
||||
if app.Donate != "" { |
||||
p("Donate :", "%s", app.Donate) |
||||
} |
||||
if app.Bitcoin != "" { |
||||
p("Bitcoin :", "bitcoin:%s", app.Bitcoin) |
||||
} |
||||
if app.Litecoin != "" { |
||||
p("Litecoin :", "litecoin:%s", app.Litecoin) |
||||
} |
||||
if app.Dogecoin != "" { |
||||
p("Dogecoin :", "dogecoin:%s", app.Dogecoin) |
||||
} |
||||
if app.FlattrID != "" { |
||||
p("Flattr :", "https://flattr.com/thing/%s", app.FlattrID) |
||||
} |
||||
fmt.Println() |
||||
p("Description :", "") |
||||
fmt.Println() |
||||
app.TextDesc(os.Stdout) |
||||
fmt.Println() |
||||
p("Available Versions :", "") |
||||
for _, apk := range app.Apks { |
||||
fmt.Println() |
||||
p(" Name :", "%s (%d)", apk.VName, apk.VCode) |
||||
p(" Size :", "%d", apk.Size) |
||||
p(" MinSdk :", "%d", apk.MinSdk) |
||||
if apk.MaxSdk > 0 { |
||||
p(" MaxSdk :", "%d", apk.MaxSdk) |
||||
} |
||||
if apk.ABIs != nil { |
||||
p(" ABIs :", "%s", strings.Join(apk.ABIs, ", ")) |
||||
} |
||||
} |
||||
} |
||||
Loading…
Reference in new issue