Fix building

If you try to build from development branch, the result is not usable. I’ll explain the hacks you need to make it work.

Problem 1: 403 on nw:build

As reported on github:

Background on nw-builder

Basically what nw-builder does is that it fetches the prebuilt binaries of nw.js and copy the source code of your app and bundles it into a package. It is also possible to directly run your app without bundling it using the method described in the nw.js documentation:

cd /path/to/your/app
/path/to/nw .

According to this comment:

Just for you know that we have an strong dependency on NW, which is compiled PCT team.
PCT NW are compiled with anothers video codecs (something like that).
Maybe you should know this.

Note: I copy the entire contents from links in case of DMCA takedowns

Since the PCT binary URL is returns 403 now (not sure if it’s due to DMCA takedown), I thought about using the vanilla binaries instead, but this way we would lose a few codecs. Then I figured I can extract the binaries from the working packaged version 0.3.9 (it’s on the front page).

Download it, unzip it, copy to popcorn-desktop/cache/0.12.2/osx64/, and rm -r popcorn-desktop/cache/0.12.2/osx64/ otherwise nwjs will simply look for source code inside app.nw to run instead of your repo source code at popcorn-desktop.

Now we can start popcorntime from your source code with:

cd popcorntime-desktop
cache/0.12.2/osx64/ –development .

Note: I read somewhere of the --development flag, but don’t observe any change in behavior, I’ll just leave it there.

Soon you’ll hit error like this (debug log at popcorn-desktop/cache/0.12.2/osx64/

[43854:0710/142626:INFO:CONSOLE(27)] ""added" "TVShowTime" "to provider registry"", source: app://host/src/app/lib/providers/generic.js (27)
[43854:0710/142626:INFO:CONSOLE(35)] ""loaded" "tvshowtime.js"", source: app://host/src/app/bootstrap.js (35)
[43854:0710/142626:INFO:CONSOLE(27)] ""added" "Watchlist" "to provider registry"", source: app://host/src/app/lib/providers/generic.js (27)
[43854:0710/142626:INFO:CONSOLE(35)] ""loaded" "watchlist.js"", source: app://host/src/app/bootstrap.js (35)
[43854:0710/142626:INFO:CONSOLE(27)] ""added" "ysubs" "to provider registry"", source: app://host/src/app/lib/providers/generic.js (27)
[43854:0710/142626:INFO:CONSOLE(35)] ""loaded" "ysubs.js"", source: app://host/src/app/bootstrap.js (35)
[43854:0710/142626:INFO:CONSOLE(21)] ""%c[%cERROR%c] Error starting up" "color: black;" "color: red;" "color: black;"", source: app://host/src/app/app.js (21)
[43854:0710/142626:INFO:CONSOLE(16)] ""[%cWARNING%c] Show Disclaimer" "color: orange;" "color: black;"", source: app://host/src/app/app.js (16)

Problem 2: Error starting up

With my limited Javascript knowledge, I added the lines to print out debug messages at app/database.js#447:

446             .catch(function (err) {
447                 console.log(err.message);
448                 console.log(err.stack);
449                 win.error('Error starting up', err);

Got the error:

Error: Cannot find module 'butter-provider-MovieApi'
at Function.Module._resolveFilename (module.js:327:15)
at Function.Module._load (module.js:264:25)
at Module.require (module.js:356:17)
at require (module.js:375:17)
at window.require (\u003Canonymous\u003E:4:17)
at Object.getProvider [as get] (app://host/src/app/lib/providers/generic.js:54:60)
at app://host/src/app/lib/config.js:227:42
at (app://host/src/app/vendor/underscore/underscore.js:172:24)
at Object.Config.getProviderForType (app://host/src/app/lib/config.js:226:26)
at app://host/src/app/bootstrap.js:85:42
at (native)
at app://host/src/app/bootstrap.js:83:56
at Promise_then_fulfilled (/Users/pellaeon/project/popcorn-desktop/node_modules/q/q.js:766:44)
at Promise_done_fulfilled (/Users/pellaeon/project/popcorn-desktop/node_modules/q/q.js:835:31)
at Fulfilled_dispatch [as dispatch] (/Users/pellaeon/project/popcorn-desktop/node_modules/q/q.js:1229:9)
at Pending_become_eachMessage_task (/Users/pellaeon/project/popcorn-desktop/node_modules/q/q.js:1369:30)"", source: app://host/src/app/database.js (448)

grepping butter-provider-MovieApi in the source tree returns no result, neither does googling.

Then I tried copying the entire working source tree from the packaged version, this doesn’t make the error go away either, which indicates that the problem lies not in the source tree. But where could the problem be?

The only one I could think of was the 2 files you need to download separately from to build it: and (instructions in readme). Anyway this doesn’t work either.

I came across issue#102:

The downloaded is invalid, after pct load the file, it is not added to provider registry. I changed ysubs.js minified content by ysubs.js from branch feature/electron (old version of the file) and it works.

Hmmm, very suspicious.

But diffing ysubs.js doesn’t seem the downloaded version have anything different that would make the error go away, nor does actually installing it, nor is torrent_collection.js, which lies inside the view directory, even less likely.

So looks like I need to dig in to the trace to see what I have missed.

Digging into the code

With the trace above, I decided to go with bootstrap.js first, between line 83 and 85, let’s print out the variable first:

83             return _.filter(_.keys(Settings.providers).map(function (type) {
84                 console.log('========1');
85                 console.log(type);
86                 return {
87                     provider: App.Config.getProviderForType(type),
88                     type: type
89                 };

Running again, the log gives:

[46099:0710/164418:INFO:CONSOLE(84)] ""========1"", source: app://host/src/app/bootstrap.js (84)
[46099:0710/164418:INFO:CONSOLE(85)] ""movie"", source: app://host/src/app/bootstrap.js (85)

Hmmm, nothing too special, don’t look deeper just now.

Let’s see what it later calls: getProviderForType(). See the vars again:

225             } else if (provider instanceof Array || typeof provider === 'object') {
226                 return, function (t) {
227                     console.log('==========2');
228                     console.log(t);
229                     return App.Providers.get(t);
230                 });
231             } else {
232                 return App.Providers.get(provider);
233             }


[46099:0710/164418:INFO:CONSOLE(227)] ""==========2"", source: app://host/src/app/lib/config.js (227)
[46099:0710/164418:INFO:CONSOLE(228)] ""MovieApi?&apiURL=,"", source: app://host/src/app/lib/config.js (228)

…wait, isn’t that the non-existent module’s name? “butter-provider-MovieApi“, and after that a URL that doesn’t look valid at all:, verryyy suspicious (Note: I later found out it is actually valid URL). grep it:

popcorn-desktop$ grep -R 'MovieApi' *
node_modules/             uri: ['MovieApi?'

What ?!! node_modules ! It gets settings from node_modules ?!

grep in packaged version returned no result. So this is what differs between 2 versions!

I copied index.js from packaged version to popcorn-desktop/node_modules..., and this time it started successfully, and is able to load all movies and TV shows!

What really happened

Looking at package.json from the 2 different directory, seems like the two do differ in versions, master uses c745869979405d02d5a4cfea066c227801ee0fc2 (of, 0.3.9 uses 6b8075e0065efbe7276e4a469ca00dbc43c2aaa9. diff:

git diff 6b8075e0065efbe7276e4a469ca00dbc43c2aaa9..HEAD
diff --git a/index.js b/index.js
index dce0e24..ccfcec1 100644
--- a/index.js
+++ b/index.js
@@ -16,10 +16,10 @@ module.exports = {
movie: {
order: 1,
name: 'Movies',
-             uri: ['yts?'
+             uri: ['MovieApi?'
-                     + ','
-//                     + 'cloudflare+,'
+                     + ','
+//                     + 'cloudflare+,'
//                     + 'cloudflare+'
@@ -28,8 +28,8 @@ module.exports = {
name: 'Series',
uri: ['TVApi?'
-                     + ','
-//                     + ','
+                     + ','
+//                     + 'cloudflare+,'
//                     + ''

Testing the URLs in it I found it is actually valid (must be the new gTLDs).

Seems like the name before the question mark is the key, there is butter-provider-yts but no butter-provider-MovieApi in node_modules, so it couldn’t load the latter and errored.

Butter will automatically load any npm package installed (listed in package.json) that matches the =/butter-provider-.*/ regex.

I guess this is in startup stage, and in later stage someone would request the MovieApi or yts provider, but I still haven’t found the code.

Anyway, this fixes the build, so another time!


在下方填入你的資料或按右方圖示以社群網站登入: Logo

You are commenting using your account. Log Out / 變更 )

Twitter picture

You are commenting using your Twitter account. Log Out / 變更 )


You are commenting using your Facebook account. Log Out / 變更 )

Google+ photo

You are commenting using your Google+ account. Log Out / 變更 )

連結到 %s