Browse Source

Do not show the blacklisted extensions

Eric Charles 5 years ago
parent
commit
b8f299ed26

+ 3 - 1
packages/extensionmanager-extension/examples/listings/Makefile

@@ -1,5 +1,7 @@
 export BLACK_LIST_URIS="https://raw.githubusercontent.com/datalayer-jupyterlab/jupyterlab-listings-example/master/blacklist_simple.json"
-export WHITE_LIST_URIS="https://raw.githubusercontent.com/datalayer-jupyterlab/jupyterlab-listings-example/master/whitelist_simple.json"
+# export WHITE_LIST_URIS=""
+# export BLACK_LIST_URIS="https://raw.githubusercontent.com/datalayer-jupyterlab/jupyterlab-listings-example/master/blacklist_simple.json"
+export WHITE_LIST_URIS=""
 export LISTINGS_REFRESH_MS=30000
 export LISTINGS_REQUEST_OPTS="{'timeout': 10}"
 

+ 1 - 3
packages/extensionmanager-extension/listing/listings.json

@@ -3,9 +3,7 @@
     "blacklist_uris": [
       "https://raw.githubusercontent.com/jupyterlab/listings/master/blacklist.json"
     ],
-    "whitelist_uris": [
-      "https://raw.githubusercontent.com/jupyterlab/listings/master/whitelist.json"
-    ],
+    "whitelist_uris": [""],
     "blacklist": [],
     "whitelist": ["@jupyterlab/*"]
   }

+ 17 - 7
packages/extensionmanager/src/listings.ts

@@ -27,6 +27,10 @@ export interface IListEntry {
  *
  */
 export interface IListResult {
+  /**
+   * The mode for the listings, can be black or white.
+   */
+  listMode: 'white' | 'black' | null;
   /**
    * A collection of URIs for black listings.
    */
@@ -56,7 +60,7 @@ export interface IListingApi {
 }
 
 /**
- * An object for getting listings from URIs.
+ * An object for getting listings from the server API.
  */
 export class Lister {
   /**
@@ -67,12 +71,17 @@ export class Lister {
       '@jupyterlab/extensionmanager-extension/listings.json'
     )
       .then(data => {
-        this._listings = {
-          blacklistUris: data.blacklist_uris,
-          whitelistUris: data.whitelist_uris,
-          blacklist: data.blacklist,
-          whitelist: data.whitelist
-        };
+        if (
+          !(data.blacklist_uris.length > 0 && data.whitelist_uris.length > 0)
+        ) {
+          this._listings = {
+            listMode: data.blacklist_uris.length > 0 ? 'black' : 'white',
+            blacklistUris: data.blacklist_uris,
+            whitelistUris: data.whitelist_uris,
+            blacklist: data.blacklist,
+            whitelist: data.whitelist
+          };
+        }
         this._listingsLoaded.emit(this._listings);
       })
       .catch(error => {
@@ -85,6 +94,7 @@ export class Lister {
   }
 
   private _listings: IListResult = {
+    listMode: null,
     blacklistUris: [],
     whitelistUris: [],
     blacklist: [],

+ 41 - 19
packages/extensionmanager/src/model.ts

@@ -170,7 +170,8 @@ export class ListModel extends VDomModel {
     });
   }
 
-  _listingIsLoaded(_: Lister, listings: IListResult) {
+  private _listingIsLoaded(_: Lister, listings: IListResult) {
+    this._listMode = listings.listMode;
     this._blacklistMap = new Map<string, IListEntry>();
     listings.blacklist.map(e => {
       this._blacklistMap.set(e.name, {
@@ -194,22 +195,6 @@ export class ListModel extends VDomModel {
       });
     });
     void this.initialize();
-    /*
-    this.performGetBlacklist()
-      .then(data => {
-        this._blacklistingMap = data;
-      })
-      .catch(error => {
-        console.error(error);
-      });
-    this.performGetWhitelist()
-      .then(data => {
-        this._whitelistingMap = data;
-      })
-      .catch(error => {
-        console.error(error);
-      });
-    */
   }
 
   /**
@@ -278,6 +263,27 @@ export class ListModel extends VDomModel {
     return this._totalEntries;
   }
 
+  /**
+   * The list mode.
+   */
+  get listMode(): 'black' | 'white' | null {
+    return this._listMode;
+  }
+
+  /**
+   * The total number of blacklisted results in the current search.
+   */
+  get totalBlacklistedFound(): number {
+    return this._totalBlacklistedFound;
+  }
+
+  /**
+   * The total number of whitelisted results in the current search.
+   */
+  get totalWhitelistedFound(): number {
+    return this._totalWhitelistedFound;
+  }
+
   /**
    * Initialize the model.
    */
@@ -461,11 +467,23 @@ export class ListModel extends VDomModel {
     res: Promise<ISearchResult>
   ): Promise<{ [key: string]: IEntry }> {
     let entries: { [key: string]: IEntry } = {};
+    this._totalBlacklistedFound = 0;
+    this._totalWhitelistedFound = 0;
+    this._totalEntries = 0;
     for (let obj of (await res).objects) {
       let pkg = obj.package;
       if (pkg.keywords.indexOf('deprecated') >= 0) {
         continue;
       }
+      this._totalEntries = this._totalEntries + 1;
+      const isBlacklisted = this.isListed(pkg.name, this._blacklistMap);
+      if (isBlacklisted) {
+        this._totalBlacklistedFound = this._totalBlacklistedFound + 1;
+      }
+      const isWhitelisted = this.isListed(pkg.name, this._whitelistMap);
+      if (isWhitelisted) {
+        this._totalWhitelistedFound = this._totalWhitelistedFound + 1;
+      }
       entries[pkg.name] = {
         name: pkg.name,
         description: pkg.description,
@@ -480,8 +498,8 @@ export class ListModel extends VDomModel {
         status: null,
         latest_version: pkg.version,
         installed_version: '',
-        blacklistEntry: this.isListed(pkg.name, this._blacklistMap),
-        whitelistEntry: this.isListed(pkg.name, this._whitelistMap)
+        blacklistEntry: isBlacklisted,
+        whitelistEntry: isWhitelisted
       };
     }
     return entries;
@@ -789,8 +807,12 @@ export class ListModel extends VDomModel {
   private _searchResult: IEntry[];
   private _pendingActions: Promise<any>[] = [];
   private _debouncedUpdate: Debouncer<void, void>;
+
+  private _listMode: 'black' | 'white' | null;
   private _blacklistMap: Map<string, IListEntry>;
   private _whitelistMap: Map<string, IListEntry>;
+  private _totalBlacklistedFound: number = 0;
+  private _totalWhitelistedFound: number = 0;
 }
 
 let _isDisclaimed = false;

+ 62 - 13
packages/extensionmanager/src/widget.tsx

@@ -179,7 +179,7 @@ namespace BuildPrompt {
  * VDOM for visualizing an extension entry.
  */
 function ListEntry(props: ListEntry.IProperties): React.ReactElement<any> {
-  const { entry } = props;
+  const { entry, listMode } = props;
   const flagClasses = [];
   if (entry.status && ['ok', 'warning', 'error'].indexOf(entry.status) !== -1) {
     flagClasses.push(`jp-extensionmanager-entry-${entry.status}`);
@@ -194,6 +194,9 @@ function ListEntry(props: ListEntry.IProperties): React.ReactElement<any> {
   if (entry.blacklistEntry) {
     flagClasses.push(`jp-extensionmanager-entry-is-blacklisted`);
   }
+  if (entry.blacklistEntry?.name && listMode === 'black') {
+    return <li></li>;
+  }
   return (
     <li
       className={`jp-extensionmanager-entry ${flagClasses.join(' ')}`}
@@ -294,6 +297,8 @@ export namespace ListEntry {
      */
     entry: IEntry;
 
+    listMode: 'black' | 'white' | null;
+
     /**
      * Callback to use for performing an action on the entry.
      */
@@ -310,6 +315,7 @@ export function ListView(props: ListView.IProperties): React.ReactElement<any> {
     entryViews.push(
       <ListEntry
         entry={entry}
+        listMode={props.listMode}
         key={entry.name}
         performAction={props.performAction}
       />
@@ -368,6 +374,8 @@ export namespace ListView {
      */
     numPages: number;
 
+    listMode: 'black' | 'white' | null;
+
     /**
      * The callback to use for changing the page
      */
@@ -380,6 +388,18 @@ export namespace ListView {
   }
 }
 
+function ListingMessage(props: ListingMessage.IProperties) {
+  return (
+    <div className="jp-extensionmanager-listingmessage">{props.children}</div>
+  );
+}
+
+namespace ListingMessage {
+  export interface IProperties {
+    children: React.ReactNode;
+  }
+}
+
 function ErrorMessage(props: ErrorMessage.IProperties) {
   return (
     <div key="error-msg" className="jp-extensionmanager-error">
@@ -535,7 +555,7 @@ export class ExtensionView extends VDomRenderer<ListModel> {
     if (model.promptBuild) {
       elements.push(
         <BuildPrompt
-          key="buildpromt"
+          key="promt"
           performBuild={() => {
             model.performBuild();
           }}
@@ -601,6 +621,7 @@ export class ExtensionView extends VDomRenderer<ListModel> {
         installedContent.push(
           <ListView
             key="installed-items"
+            listMode={model.listMode}
             entries={model.installed}
             numPages={1}
             onPage={value => {
@@ -642,18 +663,46 @@ export class ExtensionView extends VDomRenderer<ListModel> {
         );
       } else {
         searchContent.push(
-          <ListView
-            key="search-items"
-            // Filter out installed extensions:
-            entries={model.searchResult.filter(
-              entry => model.installed.indexOf(entry) === -1
+          <>
+            {model.listMode === 'black' && model.totalEntries > 0 && (
+              <ListingMessage>
+                {
+                  <a
+                    href="https://jupyterlab.readthedocs.io/en/latest/user/extensions.html"
+                    target="_blank"
+                  >
+                    {model.totalBlacklistedFound} extensions out of the&nbsp;
+                    {model.totalEntries} found are blacklisted and are not&nbsp;
+                    shown.
+                  </a>
+                }
+              </ListingMessage>
             )}
-            numPages={pages}
-            onPage={value => {
-              this.onPage(value);
-            }}
-            performAction={this.onAction.bind(this)}
-          />
+            {model.listMode === 'white' && model.totalEntries > 0 && (
+              <ListingMessage>
+                <a
+                  href="https://jupyterlab.readthedocs.io/en/latest/user/extensions.html"
+                  target="_blank"
+                >
+                  {model.totalWhitelistedFound} extensions out of the&nbsp;
+                  {model.totalEntries} found are whitelisted.
+                </a>
+              </ListingMessage>
+            )}
+            <ListView
+              key="search-items"
+              listMode={model.listMode}
+              // Filter out installed extensions:
+              entries={model.searchResult.filter(
+                entry => model.installed.indexOf(entry) === -1
+              )}
+              numPages={pages}
+              onPage={value => {
+                this.onPage(value);
+              }}
+              performAction={this.onAction.bind(this)}
+            />
+          </>
         );
       }
 

+ 11 - 0
packages/extensionmanager/style/base.css

@@ -75,6 +75,17 @@
   /* border: 1px solid var(--jp-brand-color1); */
 }
 
+/*
+  Listing messages
+*/
+.jp-extensionmanager-listingmessage {
+  background-color: var(--jp-brand-color1);
+  color: var(--jp-ui-inverse-font-color1);
+  padding: 4px 8px;
+  font-size: var(--jp-ui-font-size1);
+  font-weight: 400;
+}
+
 /*
   Error messages
 */