diff --git a/controller/Controller.class.php b/controller/Controller.class.php index 59508f3c..31f83c89 100644 --- a/controller/Controller.class.php +++ b/controller/Controller.class.php @@ -13,7 +13,18 @@ class Controller $viewParameters = isset($viewAndParams[1]) ? $viewAndParams[1] : []; $headers = isset($viewAndParams[2]) ? $viewAndParams[2] : []; - static::sendHeaders($headers); + $defaultHeaders = [ + 'Content-Security-Policy' => "frame-ancestors 'none'", + 'X-Frame-Options' => 'DENY', + 'X-XSS-Protection'=> '1', + ]; + + if (IS_PRODUCTION) + { + $defaultHeaders['Strict-Transport-Security'] = 'max-age=31536000'; + } + + static::sendHeaders(array_merge($defaultHeaders, $headers)); if ($viewTemplate === null) { @@ -47,12 +58,6 @@ class Controller { case '/': return ContentActions::executeHome(); - case '/fund': - return CreditActions::executeFund(); - case '/fund-after': - return ['fund/fund-after']; - case '/goals': - return ['fund/goals']; case '/get': case '/windows': case '/ios': @@ -66,42 +71,59 @@ class Controller return OpsActions::executeLogUpload(); case '/list-subscribe': return MailActions::executeListSubscribe(); + case '/press-kit.zip': + return ContentActions::executePressKit(); case '/LBRY-deck.pdf': - return static::redirect('https://s3.amazonaws.com/files.lbry.io/LBRY-deck.pdf', 307); - case '/dl/lbry_setup.sh': - return ['internal/dl-not-supported', ['_no_layout' => true]]; + case '/deck.pdf': + return static::redirect('https://www.dropbox.com/s/0xj4vgucsbi8rtv/lbry-deck.pdf?dl=1'); + case '/pln.pdf': + case '/plan.pdf': + return static::redirect('https://www.dropbox.com/s/uevjrwnyr672clj/lbry-pln.pdf?dl=1'); case '/lbry-osx-latest.dmg': - return static::redirect('https://github.com/lbryio/lbry/releases/download/v0.2.4/lbry.0.2.4.dmg', 307); case '/lbry-linux-latest.deb': - return static::redirect('https://github.com/lbryio/lbry/releases/download/v0.2.4/lbry_0.2.4_amd64.deb', 307); + case '/dl/lbry_setup.sh': + return static::redirect('/get', 301); case '/art': - return static::redirect('/what'); - default: - $newsPattern = '#^' . ContentActions::URL_NEWS . '(/|$)#'; - if (preg_match($newsPattern, $uri)) - { - $slug = preg_replace($newsPattern, '', $uri); - if ($slug == ContentActions::RSS_SLUG) - { - return ContentActions::executeRss(); - } - return $slug ? ContentActions::executePost($uri) : ContentActions::executeNews(); - } - $faqPattern = '#^' . ContentActions::URL_FAQ . '(/|$)#'; - if (preg_match($faqPattern, $uri)) - { - $slug = preg_replace($faqPattern, '', $uri); - return $slug ? ContentActions::executePost($uri) : ContentActions::executeFaq(); - } - $noSlashUri = ltrim($uri, '/'); - if (View::exists('page/' . $noSlashUri)) - { - return ['page/' . $noSlashUri, []]; - } - else - { - return ['page/404', [], [static::HEADER_STATUS => 404]]; - } + return static::redirect('/what', 301); + case '/why': + case '/feedback': + return static::redirect('/learn', 301); + case '/faq/when-referral-payouts': + return static::redirect('/faq/referrals', 301); + } + + $newsPattern = '#^' . ContentActions::URL_NEWS . '(/|$)#'; + if (preg_match($newsPattern, $uri)) + { + $slug = preg_replace($newsPattern, '', $uri); + if ($slug == ContentActions::RSS_SLUG) + { + return ContentActions::executeRss(); + } + return $slug ? ContentActions::executeNewsPost($uri) : ContentActions::executeNews(); + } + + $faqPattern = '#^' . ContentActions::URL_FAQ . '(/|$)#'; + if (preg_match($faqPattern, $uri)) + { + $slug = preg_replace($faqPattern, '', $uri); + return $slug ? ContentActions::executeFaqPost($uri) : ContentActions::executeFaq(); + } + $noSlashUri = ltrim($uri, '/'); + + $accessPattern = '#^/signup#'; + if (preg_match($accessPattern, $uri)) + { + return DownloadActions::executeSignup(); + } + + if (View::exists('page/' . $noSlashUri)) + { + return ['page/' . $noSlashUri, []]; + } + else + { + return ['page/404', [], [static::HEADER_STATUS => 404]]; } } diff --git a/controller/Session.class.php b/controller/Session.class.php index a7d9a49c..bebd861b 100644 --- a/controller/Session.class.php +++ b/controller/Session.class.php @@ -8,6 +8,9 @@ class Session { const KEY_MAILCHIMP_LIST_IDS = 'mailchimp_list_ids', + KEY_DOWNLOAD_ACCESS_ERROR = 'download_error2', + KEY_DOWNLOAD_ALLOWED = 'beta_download_allowed2', + KEY_PREFINERY_USER_ID = 'prefinery_user_id', KEY_LIST_SUB_ERROR = 'list_error', KEY_LIST_SUB_SIGNATURE = 'list_sub_sig', KEY_LIST_SUB_SUCCESS = 'list_success', @@ -15,7 +18,10 @@ class Session public static function init() { - session_start(); + session_start([ + 'cookie_secure' => IS_PRODUCTION, // cookie over ssl only + 'cookie_httponly' => true, // no js access + ]); } public static function get($key, $default = null) diff --git a/controller/action/ContentActions.class.php b/controller/action/ContentActions.class.php index 3cf5dae7..57f0c4ee 100644 --- a/controller/action/ContentActions.class.php +++ b/controller/action/ContentActions.class.php @@ -24,8 +24,28 @@ class ContentActions extends Actions public static function executeFaq() { $posts = Post::find(static::VIEW_FOLDER_FAQ); + + $groupNames = [ + 'getstarted' => 'Getting Started', + 'install' => 'Installing LBRY', + 'running' => 'Running LBRY', + 'wallet' => 'The LBRY Wallet', + 'hosting' => 'Hosting Content', + 'mining' => 'Mining LBC', + 'developer' => 'Developers', + 'other' => 'Other Questions', + ]; + + $groups = array_fill_keys(array_keys($groupNames), []); + + foreach($posts as $post) + { + $groups[isset($groupNames[$post->getCategory()]) ? $post->getCategory() : 'other'][] = $post; + } + return ['content/faq', [ - 'posts' => $posts + 'groupNames' => $groupNames, + 'postGroups' => $groups ]]; } @@ -52,14 +72,14 @@ class ContentActions extends Actions ]]; } - public static function executePost($relativeUri) + public static function executeNewsPost($relativeUri) { $post = Post::load(ltrim($relativeUri, '/')); if (!$post) { return ['page/404', []]; } - return ['content/post', [ + return ['content/news-post', [ 'post' => $post, View::LAYOUT_PARAMS => [ 'showRssLink' => true @@ -67,6 +87,93 @@ class ContentActions extends Actions ]]; } + public static function executeFaqPost($relativeUri) + { + $post = Post::load(ltrim($relativeUri, '/')); + if (!$post) + { + return ['page/404', []]; + } + return ['content/faq-post', [ + 'post' => $post, + ]]; + } + + public static function executePressKit() + { + $zipFileName = 'lbry-press-kit-' . date('Y-m-d') . '.zip'; + $zipPath = tempnam('/tmp', $zipFileName); + + $zip = new ZipArchive(); + $zip->open($zipPath, ZipArchive::OVERWRITE); + +// $pageHtml = View::render('page/press-kit', ['showHeader' => false]); +// $html = << +// +// +// LBRY Press Kit +// +// +// +// +// $pageHtml +// +// +//EOD; +// +// $zip->addFromString('press.html', $html); + + foreach(glob(ROOT_DIR . '/web/img/press/*') as $productImgPath) + { + $imgPathTokens = explode('/', $productImgPath); + $imgName = $imgPathTokens[count($imgPathTokens) - 1]; + $zip->addFile($productImgPath, '/logo_and_product/' . $imgName); + } + + foreach(glob(ROOT_DIR . '/posts/bio/*.md') as $bioPath) + { + list($metadata, $bioHtml) = View::parseMarkdown($bioPath); + $zip->addFile($bioPath, '/team_bios/' . $metadata['name'] . ' - ' . $metadata['role'] . '.txt'); + } + + foreach(array_filter(glob(ROOT_DIR . '/web/img/team/*.jpg'), function($path) { + return strpos($path, 'spooner') === false; + }) as $bioImgPath) + { + $imgPathTokens = explode('/', $bioImgPath); + $imgName = str_replace('644x450', 'lbry', $imgPathTokens[count($imgPathTokens) - 1]); + $zip->addFile($bioImgPath, '/team_photos/' . $imgName); + } + + + $zip->close(); + + return ['internal/zip', [ + '_no_layout' => true, + 'zipPath' => $zipPath + ], [ + 'Content-Disposition' => 'attachment;filename=' . $zipFileName, + 'X-Content-Type-Options' => 'nosniff', + 'Content-Type' => 'application/zip', + 'Content-Length' => filesize($zipPath), + ]]; + } + + public static function prepareBioPartial(array $vars) + { + $person = $vars['person']; + $path = 'bio/' . $person . '.md'; + list($metadata, $bioHtml) = View::parseMarkdown($path); + $relativeImgSrc = '/img/team/' . $person . '-644x450.jpg'; + $imgSrc = file_exists(ROOT_DIR . '/web' . $relativeImgSrc) ? $relativeImgSrc : '/img/team/spooner-644x450.jpg'; + return $vars + $metadata + [ + 'imgSrc' => $imgSrc, + 'bioHtml' => $bioHtml, + 'orientation' => 'vertical' + ]; + } + public static function preparePostAuthorPartial(array $vars) { $post = $vars['post']; diff --git a/controller/action/DownloadActions.class.php b/controller/action/DownloadActions.class.php index 798190ef..a7829452 100644 --- a/controller/action/DownloadActions.class.php +++ b/controller/action/DownloadActions.class.php @@ -1,50 +1,115 @@ ['/windows', 'Windows', 'icon-windows', '_windows'], - static::OS_OSX => ['/osx', 'OS X', 'icon-apple', '_osx'], - static::OS_LINUX => ['/linux', 'Linux', 'icon-linux', '_linux'], + static::OS_OSX => ['/osx', 'OS X', 'icon-apple', '_osx'], + static::OS_LINUX => ['/linux', 'Linux', 'icon-linux', '_linux'], static::OS_ANDROID => ['/android', 'Android', 'icon-android', '_android'], - static::OS_IOS => ['/ios', 'iOS', 'icon-mobile', '_ios'] + static::OS_IOS => ['/ios', 'iOS', 'icon-mobile', '_ios'] ]; } public static function executeGet() { + $email = static::param('e'); + if ($email) + { + $emailIsValid = filter_var($email, FILTER_VALIDATE_EMAIL); + + $user = []; + if ($emailIsValid) + { + $user = Prefinery::findUser($email); + if ($user) + { + static::setSessionVarsForPrefineryUser($user); + } + } + + if (!$emailIsValid || !$user) + { + Session::unsetKey(Session::KEY_PREFINERY_USER_ID); + Session::unsetKey(Session::KEY_DOWNLOAD_ALLOWED); + } + } + + if (!Session::get(Session::KEY_DOWNLOAD_ALLOWED)) + { + return ['download/get', ['os' => static::guessOs()]]; + } + $osChoices = static::getOses(); - $os = static::guessOs(); + $os = static::guessOs(); if ($os && isset($osChoices[$os])) { list($uri, $osTitle, $osIcon, $partial) = $osChoices[$os]; - return ['download/get', [ - 'os' => $os, - 'osTitle' => $osTitle, - 'osIcon' => $osIcon, - 'downloadHtml' => View::exists('download/' . $partial) ? - View::render('download/' . $partial) : - false + return ['download/getAllowed', [ + 'os' => $os, + 'osTitle' => $osTitle, + 'osIcon' => $osIcon, + 'prefineryUser' => $user ?: [], + 'downloadHtml' => View::exists('download/' . $partial) ? + View::render('download/' . $partial, ['downloadUrl' => static::getDownloadUrl($os)]) : + false ]]; } - return ['download/get-no-os', [ - 'isSubscribed' => in_array(Mailchimp::LIST_GENERAL_ID, Session::get(Session::KEY_MAILCHIMP_LIST_IDS, [])) - ]]; + return ['download/get-no-os']; + } + + + public static function executeSignup() + { + $email = static::param('email'); + $code = static::param('code'); + + if (!$email || !filter_var($email, FILTER_VALIDATE_EMAIL)) + { + Session::set(Session::KEY_DOWNLOAD_ACCESS_ERROR, 'Please provide a valid email. You provided: ' . htmlspecialchars($email)); + } + else + { + $referrerId = static::param('referrer_id'); + $failure = false; + try + { + MailActions::subscribeToMailchimp($email, Mailchimp::LIST_GENERAL_ID); + } + catch (MailchimpSubscribeException $e) + { + } + + try + { + $user = Prefinery::findOrCreateUser($email, $code, $referrerId); + static::setSessionVarsForPrefineryUser($user); + } + catch (PrefineryException $e) + { + $failure = true; + } + + if ($failure) + { + Session::set(Session::KEY_DOWNLOAD_ALLOWED, false); + Session::set(Session::KEY_DOWNLOAD_ACCESS_ERROR, + 'We were unable to add you to the wait list. Received error "' . $e->getMessage() . '". Please contact ' . + Config::HELP_CONTACT_EMAIL . ' if you think this is a mistake.'); + } + } + + return Controller::redirect('/get'); } public static function prepareListPartial(array $vars) @@ -55,11 +120,44 @@ class DownloadActions extends Actions ]; } + public static function prepareSignupPartial(array $vars) + { + return $vars + [ + 'defaultEmail' => static::param('e'), + 'allowInviteCode' => true, + 'referralCode' => static::param('r', '') + ]; + } + + protected static function setSessionVarsForPrefineryUser($userData) + { + Session::set(Session::KEY_DOWNLOAD_ALLOWED, in_array($userData['status'], [Prefinery::STATE_ACTIVE, Prefinery::STATE_INVITED])); + Session::set(Session::KEY_PREFINERY_USER_ID, (int)$userData['id']); + } + + public static function prepareReferPartial(array $vars) + { + $userId = (int)Session::get(Session::KEY_PREFINERY_USER_ID); + if (!$userId) + { + return null; + } + + $prefineryUser = Prefinery::findUser($userId); + + preg_match('/\?r\=(\w+)/', $prefineryUser['share_link'], $matches); + + return $vars + [ + 'prefineryUser' => $prefineryUser, + 'referralCode' => $matches[1] ?: 'unknown' + ]; + } + protected static function guessOs() { //if exact OS is requested, use that $uri = strtok($_SERVER['REQUEST_URI'], '?'); - foreach(static::getOses() as $os => $osChoice) + foreach (static::getOses() as $os => $osChoice) { if ($osChoice[0] == $uri) { @@ -89,39 +187,53 @@ class DownloadActions extends Actions return null; } -// protected static function validateDownloadAccess() -// { -// $seshionKey = 'has-get-access'; -// if (Session::get($seshionKey)) -// { -// return true; -// } -// -// if ($_SERVER['REQUEST_METHOD'] === 'POST') -// { -// $accessCodes = include ROOT_DIR . '/data/secret/access_list.php'; -// $today = date('Y-m-d H:i:s'); -// foreach($accessCodes as $code => $date) -// { -// if ($_POST['invite'] == $code && $today <= $date) -// { -// Session::set($seshionKey, true); -// Controller::redirect('/get', 302); -// } -// } -// -// if ($_POST['invite']) -// { -// Session::set('invite_error', 'Please provide a valid invite code.'); -// } -// else -// { -// Session::set('invite_error', 'Please provide an invite code.'); -// } -// -// Controller::redirect('/get', 401); -// } -// -// return false; -// } + protected static function getDownloadUrl($os, $useCache = true) + { + if (!in_array($os, array_keys(static::getOses()))) + { + throw new DomainException('Unknown OS'); + } + + $apc = $useCache && extension_loaded('apc') && ini_get('apc.enabled'); + $key = 'lbry_release_data'; + $releaseData = null; + + if ($apc) + { + $releaseData = apc_fetch($key); + } + + if (!$releaseData) + { + try + { + $releaseData = + json_decode(Curl::get('https://api.github.com/repos/lbryio/lbry/releases/latest', [], ['user_agent' => 'LBRY']), true); + if ($apc) + { + apc_store($key, $releaseData, 600); // cache for 10 min + } + } + catch (Exception $e) + { + } + } + + if (!$releaseData) + { + return null; + } + + foreach ($releaseData['assets'] as $asset) + { + if ($os == static::OS_LINUX && in_array($asset['content_type'], ['application/x-debian-package', 'application/x-deb']) || + $os == static::OS_OSX && $asset['content_type'] == 'application/x-diskcopy' + ) + { + return $asset['browser_download_url']; + } + } + + return null; + } } diff --git a/data/i18n/en.yaml b/data/i18n/en.yaml index 3c8ced62..4119103a 100644 --- a/data/i18n/en.yaml +++ b/data/i18n/en.yaml @@ -12,13 +12,19 @@ global: tagline: Play, Share, Earn. sentence: Watch, read and play in a decentralized digital library controlled by the community. title: - home: LBRY - Watch, Share, Earn + home: LBRY - Play, Share, Earn + what: "Art in the Internet Age: An Introduction to LBRY" + learn: Learn About LBRY + publish: Publish description: home: Meet LBRY, a content sharing and publishing platform that is decentralized and owned by its users. faq: Frequently asked questions about LBRY. + get: Download/install the latest version of LBRY. news: Access information and content in ways you never dreamed possible. Earn credits for your unused bandwidth and diskspace. what: Access information and content in ways you never dreamed possible. Earn credits for your unused bandwidth and diskspace. team: LBRY is founded by a team passionate about connecting producers and consumers and breaking down broken models. Learn more about them. + learn: Learn more about LBRY, the technology that puts you back in control of the internet. + publish: Publish your content on the world's first platform that leaves creators in control. email: disclaimer: You will receive 1-2 messages a month, only from LBRY, Inc. and only about LBRY. You can easily unsubscribe at any time. page: @@ -86,4 +92,5 @@ social: tweets: Tweets by @LBRYio download: main: - title: LBRY for %os% \ No newline at end of file + title: Get LBRY + signup: LBRY is currently in invite only mode. Enter your email to join the waitlist, or your email and invite code for access. \ No newline at end of file diff --git a/posts/faq/mining-credits.md b/posts/faq/mining-credits.md new file mode 100644 index 00000000..677ae431 --- /dev/null +++ b/posts/faq/mining-credits.md @@ -0,0 +1,31 @@ +--- +title: How do I mine LBRY credits? +category: mining +--- +Library Credits (LBC) are mined over a 20-year Proof of Work period. +Block rewards increase every 100 blocks by 1LBC, peak at 500, and decline slowly. + +For GPU mining, please see our list of [pools](https://lbry.io/faq/mining-pools). Each pool has a slightly different setup so please check their Getting Started page. + +For CPU mining, LBRY binaries are out for OS X and Ubuntu. Others may try compiling from source. + +## Mining on Ubuntu + +1. `wget https://s3.amazonaws.com/files.lbry.io/bins.zip` +1. `unzip bins.zip` +1. `./lbrycrdd -server -printtoconsole -gen` +1. If you need to start over, run `rm -rf bins.zip lbry* ~/.lbry*`. **Note:** this will delete your wallet and any credits you may have. + +## Mining on macOS + +1. `wget https://s3.amazonaws.com/files.lbry.io/osxbins.zip` +1. `unzip osxbins.zip` +1. `mkdir ~/Library/Application\ Support/lbrycrd` +1. `sudo chown -R "$(whoami)" ~/Library/Application\ Support/lbrycrd` +1. `echo -e "rpcuser=lbryrpc\nrpcpassword=$(env LC_CTYPE=C LC_ALL=C tr -dc A-Za-z0-9 < /dev/urandom | head -c 16 | xargs)" > ~/Library/Application\ Support/lbrycrd/lbrycrd.conf` +1. `./lbrycrdd -server -printtoconsole -gen` +1. If you need to start over, run `rm -rf bins.zip lbry* ~/.lbry ~/Library/Application\ Support/lbrycrd`. **Note:** this will delete your wallet and any credits you may have. + +## Compiling + +Join us on [Slack](https://slack.lbry.io) if you need help compiling from source! diff --git a/posts/news/52-day-in-shoes-venezuelan.md b/posts/news/52-day-in-shoes-venezuelan.md new file mode 100644 index 00000000..c03969af --- /dev/null +++ b/posts/news/52-day-in-shoes-venezuelan.md @@ -0,0 +1,109 @@ +--- +author: lbry +title: 'Walking a Day in Venezuelan Shoes' +date: '2016-07-26 00:09:18' +cover: 'venezuela.jpg' +--- +Javier, a young Venezuelan and cryptocurrency advocate, joined [LBRY’s Slack](http://slack.lbry.io/) earlier this month to get access to our beta and learn more about LBRY’s vision. + +He shared with us a brief look into his life in Venezuela, where a socialist government has mismanaged the economy to the point of destruction. The local currency, the Venezuelan bolivar, is forecast to experience [1,600% inflation next year](http://blogs.wsj.com/economics/2016/07/18/venezuelas-inflation-is-set-to-top-1600-next-year/). Inflation will reach almost 500% this year. + +Venezuelans of all income levels are struggling with crippling shortages of food, medicine, and the most basic everyday products. Riots in the streets are almost a daily occurrence. The President has just given [control of the food supply to the military](http://www.wsj.com/articles/venezuelan-president-puts-armed-forces-in-charge-of-new-food-supply-system-1468335415). + +At the time Javier joined us, we had enabled LBRY Credit (LBC) tipping on our Slack channels. Someone sent Javier a small tip, and he responded: + +>”From the deepest corner of my heart, thanks a lot sir. I live in a poor country and I starve everyday. ... I really hope we get a new president this year. I can wait no longer, if hunger or insecurity doesn't kill me, sadness will." + +We asked him to tell us his story and that is what follows, with minor edits for clarity. + +You can help Javier by sending him BTC or LBC: + +**BTC:** 35jRKCLRXjL5j8sJDJJQZHmHkMNa18EVR5 + +**LBC:** bbBNDgX9WDKEWTaGkCi7yDjcaPdRb6GM4L + +**
Walking a Day in Venezuelan Shoes
** + +*
By Javier [Name Redacted for Safety]
* + +**The day starts** + +You get up early in the morning, you clean yourself, you say hi to your family, you take your breakfast and you go to work, you meet your work schedule, you go to the supermarket and get some food, you get home, share with your family, maybe watch TV news, and then you rest to get ready for another day of living. + +I bet this sounds like the day of most of you, because that is the way it should be: You work to get bread to the table. What could defer this short description of the day of an average worker in Venezuela? The answer might take your breath away. + +While it is true that here in Venezuela you have to comply with these general guidelines, the truth is that sometimes it is not that easy. + +**May the odds be ever in your favor** + +Here’s how your day really looks in modern Venezuela. + +You get up, you clean yourself, you say hi to your family. Up to here everything is normal. Then you have to take the first important decision in your day: Should I have breakfast? + +You get paid monthly $33 VEF (Venezuelan bolivars), which is on average $1.10 US dollars per day. For 1 kg of flour, you must pay $1.4 VEF; for 1Kg of sugar you must pay $1.8; $3 for beans; even for a 2-liter Coke you must pay $1.2. You just can't afford it. + +In order to be able to buy some food, you must stand in long lines at the supermarkets for hours (4 on average) under a hot, 40°C sunny day. + +You must struggle against insecurity. In these lines people get killed by the hands of their fellow citizens. Under anguish and despair they just fall to madness, because these foods are sold on the black market for 4 times their price. Not to mention the constant threat of motorized criminals that even for an smart phone may take your life. + +Getting medicines is not easy. Old people die for lack of medicines to treat high tension and cholesterol. Even a painkiller is something that you will rarely see in a pharmacy. + +Let’s say that you managed to get some food for today, and you are healthy. What’s next? Maybe you want a little distraction – go to movie theater, perhaps. Let me tell you that on a movie and a few snacks you can easily spend $14 VEF (almost 13 days of wages). + +A car? Ha! You must work for two years without spending a single nickel in order to get an old, rusty car. + +A house? That’s 20 years of salary, and you know, don't spend a single bolivar in the meantime, because you'll take longer to save. + +**Don't think out loud** + +Maybe you feel like expressing yourself about the situation that you are living in, but hey! Don't do it on social networks, because the police might go to your home and take you to jail just because you are talking bad of the government or telling the truth. + +**Study. But not for you, for them** + +You can prepare yourself as a professional and get a PhD. But that is worth nothing because a taxi driver can earn a lot more than any professional. (No offense to taxi drivers, I'm truly thankful for your services.) + +Maybe it will work if you study in a government institution. But here, history books aren't what they used to be, because they have rewritten the whole history to make the government look illustrious, victorious, capable. + +**Clap like a seal, nod like an iguana** + +The only people that might have a chance of not going through so much (with the exception of their personal safety) are those who are in favor of and working for the government. + +Having inside work can get you food, a good salary (but not much better), and maybe you can get into any mob (Have you heard of "El cartel de los soles"?) that exists in the different organizations. They exist to get privileges like medicines. + +Take note: Saying "no" is forbidden. Missing a meeting is forbidden. Thinking different is forbidden, at least out loud. + +**Light at the end of the tunnel** + +How can you survive such a... I don't know what to call it. + +You can take my food, you can take my medicines, you can take the peace out of my house. + +But there is something that you will never take from me, and this lives in the Blockchain. + +I'm talking about cryptocurrencies. + +Unlike local currency, cryptocurrencies don't lose their value over time, they reevaluate. This is something that is worth working for. + +If I had 1000 VEF yesterday (in local currency, about $1 US dollar), then today it is enough to buy less products than yesterday. (It's true; prices change wildly from one week to the next.) + +But if yesterday I had 1 BTC, today I’m able to buy more stuff than yesterday. Magic. + +**Something that is worth it** + +And this is just BTC. Now with a twist, LBRY enters the scene. An open source library that allows me, as an artist, to share my multimedia content in exchange for cryptocurrencies. + +Besides freedom of distribution, LBRY is an open source library. Knowledge must be free and accessible to everyone. That is what LBRY aims for. + +**Conclusion** + +I'm a semi-professional young man (I couldn't finish college for monetary reasons), of low resources (unemployed for not being a professional), with an unstable feeding (my fridge broke two years ago), hated for thinking different (crypto-what? That's a lie in the eyes of my fellow countrymen). But it is time to say enough. + +I'm not afraid to express what I’m telling you here. What else could they take from me? Can you call this a life? + +My life from now on (and always should) contributes to the open source community (secrets in my eyes are tyranny) and developing cryptocurrency platforms, because they can't take those from me. Like LBC – a coin that not only will allow me earn the foods I need to survive, but also will help me express myself better to this world and at the same time make it a better place. + +Thanks LBRY team. + +Javier + +July 2016 diff --git a/view/View.class.php b/view/View.class.php index c94e296f..8d4efbcf 100644 --- a/view/View.class.php +++ b/view/View.class.php @@ -14,11 +14,13 @@ class View { const LAYOUT_PARAMS = '_layout_params'; - protected static $metaDescription = '', - $metaImg = ''; - public static function render($template, array $vars = []) { + if (static::isMarkdown($template)) + { + return static::markdownToHtml(static::getFullPath($template)); + } + if (!static::exists($template) || substr_count($template, '/') !== 1) { throw new InvalidArgumentException(sprintf('The template "%s" does not exist or is unreadable.', $template)); @@ -35,6 +37,11 @@ class View $vars = $actionClass::$method($vars); } + if ($vars === null) + { + return; + } + extract($vars); ob_start(); ob_implicit_flush(0); @@ -54,13 +61,32 @@ class View return static::interpolateTokens(ob_get_clean()); } + public static function markdownToHtml($path) + { + return ParsedownExtra::instance()->text(trim(file_get_contents($path))); + } + public static function exists($template) { return is_readable(static::getFullPath($template)); } + protected static function isMarkdown($nameOrPath) + { + return strlen($nameOrPath) > 3 && substr($nameOrPath, -3) == '.md'; + } + protected static function getFullPath($template) { + if ($template && $template[0] == '/') + { + return $template; + } + if (static::isMarkdown($template)) + { + return ROOT_DIR . '/posts/' . $template; + } + return ROOT_DIR . '/view/template/' . $template . '.php'; } @@ -69,24 +95,13 @@ class View return '/img/' . $image; } - public static function setMetaDescription($description) + public static function parseMarkdown($template) { - static::$metaDescription = $description; - } - - public static function setMetaImage($url) - { - static::$metaImg = $url; - } - - public static function getMetaDescription() - { - return static::$metaDescription ?: 'A Content Revolution'; - } - - public static function getMetaImage() - { - return static::$metaImg ?: '//lbry.io/img/lbry-dark-1600x528.png'; + $path = static::getFullPath($template); + list($ignored, $frontMatter, $markdown) = explode('---', file_get_contents($path), 3); + $metadata = Spyc::YAMLLoadString(trim($frontMatter)); + $html = ParsedownExtra::instance()->text(trim($markdown)); + return [$metadata, $html]; } public static function compileCss() diff --git a/view/template/content/faq.php b/view/template/content/faq.php index cd8e3260..b4ecc2b0 100644 --- a/view/template/content/faq.php +++ b/view/template/content/faq.php @@ -1,13 +1,18 @@ - - false]) ?> + + + false]) ?>

{{page.faq.header}}

- - + $posts): ?> +

+ + + -
> +
- + + diff --git a/view/template/content/news.php b/view/template/content/news.php index a17b78e3..d6f08533 100644 --- a/view/template/content/news.php +++ b/view/template/content/news.php @@ -1,5 +1,5 @@ - - false]) ?> + + false]) ?>
@@ -19,6 +19,6 @@
- > +
- + diff --git a/view/template/download/get.php b/view/template/download/get.php index e07bee2c..5739d2fe 100644 --- a/view/template/download/get.php +++ b/view/template/download/get.php @@ -1,26 +1,28 @@ - $osTitle])) ?> + - false]) ?> + false]) ?>
-

$osTitle]) ?>

- - - - +

{{download.main.title}}

+ +
+ + + + + - +

{{download.main.signup}}

+
- $os - ]) ?> +
- + diff --git a/view/template/fund/fund-after.php b/view/template/fund/fund-after.php deleted file mode 100644 index f3b888be..00000000 --- a/view/template/fund/fund-after.php +++ /dev/null @@ -1,21 +0,0 @@ - - -
-
-
-
- Fund LBRY -
-
-
-

Thank You!!!

-

OMG thanks for paying.

-

Here is a unique URL that you can use to refer others. You get 10% bonus credits for anyone who uses it.

-

https://lbry.io/i/butts

-

Here are some details about how to claim them or other things you would want to know.

-
-
-
-
-
- diff --git a/view/template/fund/goals.php b/view/template/fund/goals.php deleted file mode 100644 index b8d7a5f1..00000000 --- a/view/template/fund/goals.php +++ /dev/null @@ -1,42 +0,0 @@ - - - false]) ?> -
-
-
- -

- -

- -

Core development continues through 2016.

- - -

Android and iPhone so cool.

- -
-
-
- 'Core Development Continues', - 'amount' => 25000, - 'rewardHtml' => $coreDevRewardHtml - ], [ - 'name' => 'Android and iPhone Apps', - 'amount' => 50000, - 'rewardHtml' => $appRewardHtml - ]] as $goal): ?> -
-

-
-
-
-
-
-
- -
-
-
-
- diff --git a/view/template/mail/_joinList.php b/view/template/mail/_joinList.php new file mode 100644 index 00000000..895f38a5 --- /dev/null +++ b/view/template/mail/_joinList.php @@ -0,0 +1,33 @@ + +
+ +
+ + + ga('send', 'event', 'Sign Up', 'Join List', ''); + twttr.conversion.trackPid('nty1x'); + fbq('track', ''); + +
+ + +
+ + + + + + + + + + + + +
+ {{email.disclaimer}} +
+ +
+ +
diff --git a/view/template/page/home.php b/view/template/page/home.php new file mode 100644 index 00000000..8d1f6c79 --- /dev/null +++ b/view/template/page/home.php @@ -0,0 +1,73 @@ +
+ + + true]) ?> +
+
+
+
+
+

{{global.tagline}}

+

{{global.sentence}}

+
+ + + +
+ + + others in + + ', $labels) ?> + +
+ */ ?> + +
+ +
+
+
+
+
+

+ 'Go', + 'listId' => Mailchimp::LIST_GENERAL_ID, + 'mergeFields' => ['CLI' => 'No'], + 'meta' => true, + 'returnUrl' => '/', + 'btnClass' => 'btn-alt' + ]) ?> +
+
+
+ +
+
+ +
+
+
+
+
diff --git a/view/template/page/learn.php b/view/template/page/learn.php index 3ee5ebd2..3b3d2287 100644 --- a/view/template/page/learn.php +++ b/view/template/page/learn.php @@ -1,39 +1,61 @@ - - - false]) ?> + + + false]) ?>
-
-

LBRY in 60 Seconds

- +
+
+

LBRY in 100 Seconds

+ +

Art in the Internet Age

-

Learn how LBRY will forever improve how
we create and share with one another.

+

Learn how LBRY will forever improve how we create and share with one another.

-
-
-
-

-

-
- -
-

Talk With Us

- -
-
-
-

Nerd With Us

-

LBRY is a completely open source protocol that provides a decentralized digital marketplace.

- +
+ +
+

Nerd Out

+

LBRY is 100% open source in the Bazaar tradition.

+ +
+
+
+
+
+
+
+
+
+
+

+

+ +
+
+

Join Us

+ +
+
@@ -98,4 +120,4 @@
*/ ?> - \ No newline at end of file + diff --git a/view/template/page/publish.php b/view/template/page/publish.php new file mode 100644 index 00000000..0b046ad1 --- /dev/null +++ b/view/template/page/publish.php @@ -0,0 +1,112 @@ + + + + true, 'isAbsolute' => true]) ?> +
+ +
+

Publish on LBRY

+
+ Earn $1,000 and join the next content epoch: the viewer and you, with nobody in between. +
+ Keep Reading +
+
+
+
+
+

Publishing Partnership

+

How It Works

+
    +
  • + Publish five pieces of content with the LBRY app. +
    Existing content is okay, so long as it's content you created.
    +
  • +
  • Set any price per view — from zero to a dime to one million dollars — you’re in control.
  • +
  • Receive 100% of your list price in real time as it is streamed.
  • +
  • + Receive approximately $1,000.
    + +
  • +
  • Answer our beta feedback survey about your experience.
  • +
+
+
+
+
+
+
+

What is LBRY?

+

Watch "LBRY in 100 Seconds", an introduction to the wonderful technology of LBRY.

+ +
+
+
+
+
+
+
+
+

You was inspired by the world; allow the world to be inspired by [you]

+
+ J. Cole, Note to Self +
+
+
+
+
+
+
+

Why LBRY?

+

More, Better Profit

+

Any price you charge for content settles near-instantly into an account only you control. You receive 100% of the price. Micro-payments (and free content) supported.

+

Open, Trustworthy Technology

+

+ LBRY uses the ground-breaking innovation of the blockchain to leave no one in control of your content except for you (including us!).

+

+ LBRY is an open-source protocol that is controlled by it's users: we could not change the rules even if wanted to. +

+

Complete Creator Control

+

Update your content at any time. Change the price. Change the title. Publish, unpublish. You and only you can do this in LBRY.

+ + +
+
+
+
+
+
+

What You Get

+
    +
  • Premier Partner status. Receive insider access and support for life.
  • +
  • Content featured on the LBRY landing screen seen by all users, as well as on our blog, social media, and 100,000 person email list, including links to your YouTube or other profiles.
  • +
  • + Receive $1,000 worth of LBRY credits to hold, use or sell. +
    + We make no guarantee of the value of a credit, but credits are actively traded. Current credit price can be seen + here or here. +
    +
  • +
  • We hold your hand every step of the way while taking none of your revenue.
  • +
+

What You Give

+
    +
  • Upload five videos via the LBRY interface (we’ll help you out).
  • +
  • A single social media mention about your availability on LBRY.
  • +
  • Allowance for us to promote availability of your content.
  • +
+
+
+
+
+
+

Get In Now

+ +

Questions?

+

Email Reilly Smith with questions or to schedule a call.

+ 'reilly-smith', 'orientation' => 'horizontal']) ?> +
+ true]) ?> +
+ diff --git a/view/template/page/team.php b/view/template/page/team.php index 242b2541..dff2c893 100644 --- a/view/template/page/team.php +++ b/view/template/page/team.php @@ -1,139 +1,30 @@ - - - false]) ?> + + + false]) ?>
-

{{page.team.header}}

-

{{page.team.people}}

+

The Team

+

LBRY is made possible by more people than we could ever list here. The founding team is listed below.

+
-
-
- Jeremy Kauffman + +
+ $bioSlug]) ?>
-
-

Jeremy Kauffman

-
{{page.team.jeremy.title}}
-

- {{page.team.jeremy.parag1}} -

-

- {{page.team.jeremy.parag2}} -

-

- {{page.team.jeremy.parag3}} -

-
-
-
-
- Michael Zargham -
-
-

Michael Zargham

-
{{page.team.zargham.title}}
-

- {{page.team.zargham.parag1}} -

-

- {{page.team.zargham.parag2}} -

-
-
+
+
-
-
- Josh Finer -
-
-

Josh Finer

-
{{page.team.josh.title}}
-

- {{page.team.josh.parag1}} -

- {{page.team.josh.parag2}} -

-
-
-
-
- Jimmy Kiselak -
-
-

- Jimmy Kiselak - -

-
{{page.team.jimmy.title}}
-

- {{page.team.jimmy.parag1}} -

-

- {{page.team.jimmy.parag2}} -

-

- {{page.team.jimmy.parag3}} -

-
-
-
-
-
-
- Mike Vine -
-
-

Mike Vine

-
{{page.team.mike.title}}
-

- {{page.team.mike.parag1}} -

-

- {{page.team.mike.parag2}} -

-
-
-
-
- Alex Grin -
-
-

Alex Grin

-
{{page.team.grin.title}}
-

- {{page.team.grin.parag1}} -

-

- {{page.team.grin.parag2}} -

- {{page.team.grin.parag3}} -

-
-
-
-
- -
-
- Jack Robison -
-
-

Jack Robison

-
{{page.team.jack.title}}
-

- {{page.team.jack.parag1}} -

-

- {{page.team.jack.parag2}} -

- {{page.team.jack.parag3}} -

-
-
+
- you! + you!

{{page.team.you.header}}

@@ -147,66 +38,18 @@

{{page.team.advisory}}

-
- Alex Tabarrok -
-
-

Alex Tabarrok

-
{{page.team.alex.title}}
-

{{page.team.alex.parag1}} -

-

{{page.team.alex.parag2}} -

-

{{page.team.alex.parag3}} -

-
+ 'alex-tabarrok']) ?>
-
- Stephan Kinsella -
-
-

Stephan Kinsella

-
{{page.team.stephan.title}}
-

- {{page.team.stephan.parag1}} -

-

- {{page.team.stephan.parag2}} -

-
+ 'stephan-kinsella']) ?>
-
- Michael Huemer -
-
-

Michael Huemer

-
{{page.team.michael.title}}
-

- {{page.team.michael.parag1}} -

-

- {{page.team.michael.parag2}} -

-
-
-
-
- you! -
-
-

{{page.team.you.header}}

-
{{page.team.you.advheader}}
-

- {{page.team.you.advtext}} -

-
+ 'michael-huemer']) ?>
- +
- + diff --git a/view/template/page/what.php b/view/template/page/what.php index 6c87d807..49bf05e2 100644 --- a/view/template/page/what.php +++ b/view/template/page/what.php @@ -1,6 +1,7 @@ - + + - true, 'isAbsolute' => true]) ?> + true, 'isAbsolute' => true]) ?>

Art in the Internet Age

@@ -50,7 +51,7 @@
  • Domain names are controlled via ongoing auction. This facilitates names being controlled by the publishers that value them most. These transactions take place via an electronic currency called LBRY credits, or LBC. This is covered in more detail, below.
  • -

    While creating a protocol that we ourselves cannot control sounds chaotic, it is actually about establishing trust. Every other publishing system requires trusting an intermediary that can unilaterally change the rules on you. What happens when you build your business on YouTube or Amazon and they change fees? Or Apple drops your content because the Premier of China thought your comedy went to far?

    +

    While creating a protocol that we ourselves cannot control sounds chaotic, it is actually about establishing trust. Every other publishing system requires trusting an intermediary that can unilaterally change the rules on you. What happens when you build your business on YouTube or Amazon and they change fees? Or Apple drops your content because the Premier of China thought your comedy went too far?

    Only LBRY consists of a known, promised set of rules that no one can unilaterally change. LBRY provides this by doing something unique: leaving the users in control rather than demanding that control for itself.

    2If it worries you that LBRY's decentralized nature facilitates infringing or unsavory content, this is addressed in Combatting the Ugly.
    @@ -74,7 +75,7 @@ The data and technology that makes the entire interaction possible is not reliant on nor controlled by any single entity.

    -

    The LBRY Network

    +

    The LBRY Network

    To understand precisely what LBRY is and why it matters, one must understand both LBRY as a protocol and the services the protocol enables. HTTP is the protocol that makes web browsing possible, but it would be of little interest without the service of a web browser!

    To understand LBRY, think of LBRY in terms of two layers: protocol and service. The protocol provides a fundamental, underlying technological capability. The service layer utilizes the protocol to do something that a human being would actually find useful.

    @@ -169,20 +170,20 @@

    Essentially, rather than issue a transaction to the core blockchain, transactions are issued to a 3rd-party provider. These providers have a substantial number of coins which are used to maintain balances internally and settle a smaller number of transactions to the core chain. In exchange, these providers earn a small fee, less than the fee required to issue the transaction directly to the blockchain.

    -

    LBRY Credits

    +

    LBRY Credits

    LBRY Credits, or LBC, are the unit of account for LBRY. Eventually 1,000,000,000 LBC will exist, according to a defined schedule over 20 years. The schedule decays exponentially, with around 100,000,000 in the first year.

    Additionally, some credits are awarded on a fixed basis. The total break down looks like this:

      -
    • 10% for organizations, charities, and other strategic partners. Organizations the EFF, ACLU, and others that have fought for digital rights and the security and freedom of the internet.
    • +
    • 10% for organizations, charities, and other strategic partners. Organizations like the EFF, ACLU, and others that have fought for digital rights and the security and freedom of the internet.
    • 20% for adoption programs. We’ll be giving out lots of bonus credits, especially in the early days of LBRY, in order to encourage participation. We will also look to award credits broadly, ensuring the marketplace is egalitarian.
    • 10% for us. For operational costs as well as profit.
    • 60% earned by LBRY users, via mining the LBRY cryptocurrency.
    -

    More on Naming

    +

    More on Naming

    LBRY names are one of the most unique aspects of LBRY and one that we believe will play a big role in helping it succeed.

    Control of a LBRY name is awarded via a continuous running auction in LBC. Bids are entered into a trustless escrow, marking the credits as unspendable, but leaving them intact. When a user looks up a name, the name resolves to the largest bid made by a party or parties. The ability for any number of people to have a say in where a name resolves is part of what makes LBRY a system controlled by its users. As the credits are distributed primarily among users and producers, it is community itself that has ultimate controls over the catalogue of what is available.

    @@ -214,7 +215,7 @@

    And of course, let’s not forget that LBRY users are still subject to the DMCA and other laws governing intellectual property. Users who publishing infringing content are still subject to penalties for doing so in exactly the same way they would be via BitTorrent. LBRY only adds to the suite of options available. This makes LBRY a strict improvement over BitTorrent with regards to illegal usages, which provides none of the mechanisms listed.

    -

    Our Values

    +

    Our Values

    We want to be the first digital content marketplace to:

      @@ -231,7 +232,7 @@
    -

    TL;DR

    +

    TL;DR

    Digital art is one of the first goods to evolve beyond scarcity. This evolution is changing the way content is discovered, publicized, paid for and delivered. Heretofore, the lack of transparency and monetization mechanisms in peer-to-peer sharing networks has largely enabled piracy. By equipping a peer-to-peer protocol with a digital currency and transparent decentralized ledger, the LBRY protocol opens the door to a new era of digital content distribution making peer-to-peer content distribution suitable for major publishing housing, self-publishers and everyone in between.

    If LBRY succeeds, we will enter a world that is even more creative, connected, and conservatory. We will waste less and we make more. We will create a world where a teenager in Kenya and a reality star in Los Angeles use the same tool to search the same network and have access to the same results -- a world where information, knowledge, and imagination know no borders.

    @@ -239,9 +240,9 @@

    Build our dream with us. Download LBRY at lbry.io/get.

    - +
    - + Layer 1: Protocol @@ -327,4 +328,4 @@

    While payments can be issued directly on the LBRY blockchain, the LBRY protocol encourages a volume of transactions that will not scale without usage of offchain settlement.

    Essentially, rather than issue a transaction to the core blockchain, transactions are issued to a 3rd-party provider. These providers have a substantial number of coins which are used to maintain balances internally and settle a smaller number of transactions to the core chain. In exchange, these providers earn a small fee, less than the fee required to issue the transaction directly to the blockchain.

    * - */ ?> \ No newline at end of file + */ ?> diff --git a/web/css/.gitkeep b/web/css/.gitkeep old mode 100644 new mode 100755 diff --git a/web/img/blog-covers/venezuela.jpg b/web/img/blog-covers/venezuela.jpg new file mode 100644 index 00000000..8177c109 Binary files /dev/null and b/web/img/blog-covers/venezuela.jpg differ