Advertise with Googlier.comOpen Data - Benjamin Melançon
https://data.agaric.com/taxonomy/term/3/0
enResources and organizations of interest to Drutopia development
https://data.agaric.com/resources-and-organizations-interest-drutopia-development
<div class="field field-type-text field-field-description">
<div class="field-items">
<div class="field-item odd">
<h6>A biased list by Benjamin Melançon. Suggestions and edits welcome.</h6>
<p><a href="https://drutopia.org/">Drutopia</a> is an initiative to build software for grassroots groups, in part funded and hosted by a <a href="https://platform.coop/">platform cooperative</a>.</p>
<ul>
<li><a href="https://indieweb.org/">Indieweb.org</a>, home of the IndieWeb movement and IndieWebCamps to build the independent web. Focus on <a href="https://indieweb.org/Design">design</a> first (good <abbr title="user experience">UX</abbr> as the overriding concern in defining minimal <a href="https://indieweb.org/formats">formats</a> to achieve a good experience for people interacting across independent sites), <a href="https://indieweb.org/Principles">principles</a> (and <a href="https://indieweb.org/protocols">protocols</a>) over project-centrism, and <a href="https://indieweb.org/Selfdogfood">showing with prototypes</a> rather than describing.</li>
<li><a href="http://redecentralize.org/">Redecentralize.org</a>: An organization dedicated to decentralizing the Internet to make it <a href="http://redecentralize.org/about/">resilient, private, and competitive/innovative</a>.</li>
</ul>
<p>Update: I also started an etherpad, editable by anyone, with <a href="https://pad.drutopia.org/p/drutopia-designer-dev-communities-to-contact">a list of designer and developer communities to introduce to Drutopia</a>.</p>
</div>
</div>
</div>
https://data.agaric.com/resources-and-organizations-interest-drutopia-development#commentsresourceBenjamin MelançonDrutopiadecentralizedindependenceIndieWebCampUI/UXin progressWed, 13 Dec 2017 15:14:56 +0000Benjamin Melançon3979 at https://data.agaric.comIn search of values
https://data.agaric.com/search-values
<div class="field field-type-text field-field-description">
<div class="field-items">
<div class="field-item odd">
<p>Here's a collection of value statements at diverse companies, as Agaric considers defining some more public values ourselves.</p>
<hr />
<p>Nava <abbr title="Public Benefit Corporation">PBC</abbr> has a comprehensive set of well-thought-out values, entitled <a href="https://www.navapbc.com/values/">Nava's Core Values</a>:</p>
<blockquote><h2 id="be-active-stewards">Be Active Stewards</h2>
<p>The work we do impacts the lives of millions of people. The stakes are extremely high, so the standards we hold ourselves to must be even higher. In order to meet them, we must always listen closely to the communities we serve, and strive to develop a nuanced and insightful understanding of their experiences and needs. We must then continually advocate for these voices, both to ourselves and our partners. Only with great care and humility — a willingness to be wrong — can we build the tools that will be lasting, accessible, and truly helpful to the people who need them.</p>
<h2 id="pursue-the-root-cause">Pursue the Root Cause</h2>
<p>We are here to build better foundations, not just better facades. The problems we solve are very complex, with broad social, cultural, and civic implications. This means we must always resist the quick fix in favor of pursuing the underlying cause. Getting at the root of a problem is not easy — it requires active listening, practiced empathy, and great tenacity – but it is absolutely necessary. Where we rebuild roots, we are able to effectively and efficiently remake systems from the ground up.</p>
<h2 id="think-long-term">Think Long-term</h2>
<p>We work to make basic government services effective, efficient, and responsive to the needs of millions of people. This is a continuous process — one that will outlast election cycles and resonate across lifetimes. We can’t and won’t think about our work in terms of the daily news cycle. Instead, we recognize that it benefits from, if not requires, taking a profoundly long-term perspective.</p>
<h2 id="build-together">Build Together</h2>
<p>True partnerships are truly collaborative. Our government partners bring decades of knowledge, experience, and policy insight to the table. We have our own set of specialities in technology and design. By bringing these skillsets together, our work becomes more impactful, the systems we build more resilient, and the tools we make more comprehensive. In order to achieve this collaborative spirit, we invite feedback early and often, always provide context for our choices, and share and receive knowledge with equal levels of enthusiasm. We are committed to always working in step with our partners in government.</p>
<h2 id="inclusion-is-essential">Inclusion is Essential</h2>
<p>Outcomes are unequivocally better when they incorporate a diverse array of insights and expertise. Recognizing that, we will always deliberately and thoughtfully pursue the widest range of viewpoints and life experiences possible. This helps us do the necessary work of recognizing and questioning our own assumptions. It also helps us find stronger and more holistic solutions to the problems we are striving to solve. The people we work with, and the range of experiences they bring to the table, should be directly reflective of the communities we serve. We cannot do our work well otherwise.</p>
<h2 id="progress-takes-work">Progress Takes Work</h2>
<p>Progress takes enduring commitment and extraordinary effort. It is composed of small, daily steps — not necessarily big leaps. We celebrate the difficulty of our daily work and aspire to its undertaking with enthusiasm. That often means tackling tasks that fall outside of the job description. It also means knowing how to thrive under pressure. We believe the future belongs to people who are willing to make change happen, and we are grateful to play our part.</p>
</blockquote>
<hr />
<p>Colab, a large worker-owned digital agency we admire, simply cribbed all <a href="https://colab.coop/values/">their values</a> from the United Nations Global Compact ten principles and the International Co-operative Alliance's definition of the seven cooperative principles.</p>
<blockquote><h2 class="h2-border text--uppercase">The Ten Principles of the UN Global Compact</h2>
<div class="center-text">Human Rights</div>
<ol class="ol-default text--small">
<li>Businesses should support and respect the protection of internationally proclaimed human rights; and</li>
<li>make sure that they are not complicit in human rights abuses.</li>
</ol>
<div class="center-text">Labour</div>
<ol class="ol-default text--small" start="3">
<li>Businesses should uphold the freedom of association and the effective recognition of the right to collective bargaining;</li>
<li>the elimination of all forms of forced and compulsory labour;</li>
<li>the effective abolition of child labour; and</li>
<li>the elimination of discrimination in respect of employment and occupation.</li>
</ol>
<div class="center-text">Environment</div>
<ol class="ol-default text--small" start="7">
<li>Businesses should support a precautionary approach to environmental challenges;</li>
<li>undertake initiatives to promote greater environmental responsibility; and</li>
<li>encourage the development and diffusion of environmentally friendly technologies.</li>
</ol>
<div class="center-text">Anti-Corruption</div>
<ol class="ol-default text--small" start="10">
<li>Businesses should work against corruption in all its forms, including extortion and bribery.</li>
</ol>
<p> </p>
<p> <section class="container--text styling-markdown"></section></p>
<h2 class="h2-border text--uppercase">The Co-operative Principles of The International Co-operative Alliance</h2>
<div class="h3 center-text">Voluntary and Open Membership</div>
<ol class="ol-default text--small">
<li>Co-operatives are voluntary organisations, open to all persons able to use their services and willing to accept the responsibilities of membership, without gender, social, racial, political or religious discrimination.</li>
</ol>
<div class="h3 center-text">Democratic Member Control</div>
<ol class="ol-default text--small" start="2">
<li>Co-operatives are democratic organisations controlled by their members, who actively participate in setting their policies and making decisions. Men and women serving as elected representatives are accountable to the membership. In primary co-operatives members have equal voting rights (one member, one vote) and co-operatives at other levels are also organised in a democratic manner.</li>
</ol>
<div class="h3 center-text">Member Economic Participation</div>
<ol class="ol-default text--small" start="3">
<li>Members contribute equitably to, and democratically control, the capital of their co-operative. At least part of that capital is usually the common property of the co-operative. Members usually receive limited compensation, if any, on capital subscribed as a condition of membership. Members allocate surpluses for any or all of the following purposes: developing their co-operative, possibly by setting up reserves, part of which at least would be indivisible; benefiting members in proportion to their transactions with the co-operative; and supporting other activities approved by the membership.</li>
</ol>
<div class="h3 center-text">Autonomy and Independence</div>
<ol class="ol-default text--small" start="4">
<li>Co-operatives are autonomous, self-help organisations controlled by their members. If they enter into agreements with other organisations, including governments, or raise capital from external sources, they do so on terms that ensure democratic control by their members and maintain their co-operative autonomy.</li>
</ol>
<div class="h3 center-text">Education, Training and Information</div>
<ol class="ol-default text--small" start="5">
<li>Co-operatives provide education and training for their members, elected representatives, managers, and employees so they can contribute effectively to the development of their co-operatives. They inform the general public - particularly young people and opinion leaders - about the nature and benefits of co-operation.</li>
</ol>
<div class="h3 center-text">Co-operation among Co-operatives</div>
<ol class="ol-default text--small" start="6">
<li>Co-operatives serve their members most effectively and strengthen the co-operative movement by working together through local, national, regional and international structures.</li>
</ol>
<div class="h3 center-text">Concern for Community</div>
<ol class="ol-default text--small" start="7">
<li>Co-operatives work for the sustainable development of their communities through policies approved by their members.</li>
</ol>
</blockquote>
<hr />
<p>Perhaps taking the position that living your values is more important than stating them, <a href="https://palantetech.coop/about">Palante Tech's about page</a> simply describes what they do:</p>
<blockquote><p>
Palante Technology is a worker cooperative that provides tech consulting services to progressive nonprofit, social justice, activist and community organizations. Through this work we've developed a deep understanding of nonprofit tech needs. We have also been long involved with activism and organizing in non-technological capacities, including involvement with many of our client organizations. This breadth of experience allows Palante Tech to provide services that are tailored to meet the specialized needs of nonprofit community organizations.
</p></blockquote>
<hr />
<p>Red Hat, likewise, does not have a single values statement but talks a great deal about "the open source way", with other value statements paired with actions taken sprinkled throughout their <a href="https://www.redhat.com/en/about/company">about page</a>, such as:</p>
<p><</p>
<p>ul></p>
<li>
<hr />
<p>Way down on <a href="https://buffer.com/about">Buffer's about page</a>, beneath their philosophy, they offer "The 10 Buffer Values" which they say were influenced by Dale Carnegie (née Carnagey):</p>
<blockquote><h3>1. Choose Positivity and Happiness</h3>
<ul>
<li>You strive to approach things in a positive and optimistic way</li>
<li>You avoid criticizing or condemning team members or users</li>
<li>You avoid complaining</li>
<li>You let the other person save face, even if they are clearly wrong</li>
<li>You are deliberate about giving genuine appreciation</li>
</ul>
<h3>2. Default to Transparency</h3>
<ul>
<li>You take pride in opportunities to share our beliefs, failures, strengths and decisions</li>
<li>You use transparency as a tool to help others</li>
<li>You always state your thoughts immediately and with honesty</li>
<li>You share early in the decision process to avoid "big revelations"</li>
</ul>
<h3>3. Have a Focus on Self Improvement</h3>
<ul>
<li>You are conscious of your current level of productivity and happiness, and make continual changes to grow</li>
<li>You have a higher expectation of yourself than Buffer does of you</li>
<li>You regularly and deliberately do things that make you feel uncomfortable</li>
<li>You practice activities and develop habits that will improve your mind and body</li>
</ul>
<h3>4. Be a "no-ego" Doer</h3>
<ul>
<li>You don't attach your personal self to ideas</li>
<li>You let others have your best ideas</li>
<li>You approach new ideas thinking "what can we do right now?"</li>
<li>You are humble</li>
<li>You always ship code the moment it is better than what is live on our site - no matter what</li>
</ul>
<h3>5. Listen First, Then Listen More</h3>
<ul>
<li>You seek first to understand, then to be understood</li>
<li>You focus on listening rather than responding</li>
<li>You take the approach that everything is a hypothesis and you could be wrong</li>
<li>You are suggestive rather than instructive, replacing phrases such as 'certainly','undoubtedly', etc with 'perhaps', 'I think', 'my intuition right now'</li>
</ul>
<h3>6. Have a Bias Towards Clarity</h3>
<ul>
<li>You talk, code, design and write in a clear way instead of being clever</li>
<li>You over-communicate, repeating things more times than you would intuitively</li>
<li>You use more words to explain, even if it feels obvious already</li>
<li>You don't make assumptions, you instead ask that extra question to have the full picture</li>
</ul>
<h3>7. Make Time to Reflect</h3>
<ul>
<li>You deliberately find time for reflection, because that's where your life-changing adjustments come from</li>
<li>You have a calm approach to discussions and ponder points in your own time</li>
<li>You find time to jump out of the trenches into the higher level thinking that will move the needle</li>
<li>You understand the value of patience and treat it as a muscle which needs practice to grow</li>
</ul>
<h3>8. Live Smarter, Not Harder</h3>
<ul>
<li>You value waking up fresh over working that extra hour</li>
<li>You always aim to be fully engaged in an activity, or resting</li>
<li>You single task your way through the day</li>
<li>You are at the top of your game, as you focus on expanding capacity of your mental, physical, emotional and spiritual energy</li>
<li>You choose to be at the single place on Earth where you are the happiest, and most productive, and you are not afraid to find out where that is</li>
</ul>
<h3>9. Show Gratitude</h3>
<ul>
<li>You regularly stop and are grateful for your circumstances</li>
<li>You are grateful for the work co-workers do to push the company forward and help you move faster</li>
<li>You approach customer conversations with humility and the knowledge that it's a privilege to serve these people</li>
<li>You have gratitude for platforms, tools and open source that laid the foundation for the possibility of the company: "If I have seen further it is by standing on the shoulders of giants" - Isaac Newton</li>
</ul>
<h3>10. Do the Right Thing</h3>
<ul class="List--style-margin-bottom-0">
<li>You choose what's best for customers and the company in the long-term</li>
<li>You correct the mistake even when no one would notice</li>
<li>You strive to provide the best solution, even if that means foregoing profit</li>
<li>You get excited about opportunities to help others</li>
</ul>
</blockquote>
<p>Slack hides their core values on <a href="https://slack.com/careers" rel="nofollow">their career page</a>, and doesn't elaborate on the one-word (plus emoji) per principle, beyond a brief introduction, which is a little depressing when you realize helping people "bring more of themselves to their work" is probably the best purpose you can have while being wildly successful under capitalism:</p>
<blockquote><p>
Our core values</p>
<p>These are some of the values we live by, as a company. We work by them, too: we’re building a platform and products we believe in — knowing there is real value to be gained from helping people, wherever they are, simplify whatever it is that they do and bring more of themselves to their work.</p>
<p> Empathy emoji Empathy<br />
Courtesy emoji Courtesy<br />
Thriving emoji Thriving<br />
Craftsmanship emoji Craftsmanship<br />
Playfulness emoji Playfulness<br />
Solidarity emoji Solidarity
</p></blockquote>
<hr />
<p>Agaric doesn't currently have a values, statement of purpose, or anything else publicly.</p>
<p>This is the closest we have on our present long-neglected web site:</p>
<blockquote><p>Agaric helps people create and use powerful web sites. As a collective of skilled workers, we collaborate with you and free software communities to develop tools and build platforms that meet your needs.</p></blockquote>
<p>I've floated "the most power possible to all people over their own lives" as a statement of purpose, but that's what i put down for everything i do— it's not unique to Agaric's particular ways of helping people gain control (let alone liberty and justice, to the extent we get to do that).</p>
<p>Agaric's inward-facing values, defined in a process led by Mauricio Dinarte and captured under the heading "Culture", are really solid and I think ought to be broadcast and lived more:</p>
<blockquote><h2>Culture</h2>
<ul>
<li>We prioritize health and family over work.</li>
<li>We work for the benefit of the group.</li>
<li>We encourage continuous learning.</li>
<li>We appreciate and welcome new ideas.</li>
<li>We give back to the communities we are part of.</li>
<li>We value long term relationships.</li>
</ul>
<h2>7 Cooperative Principles</h2>
<p>Agaric is a cooperative and we work under these principles.</p>
<ul>
<li>Voluntary and Open Membership</li>
<li>Democratic Member Control</li>
<li>Members' Economic Participation</li>
<li>Autonomy and Independence</li>
<li>Education, Training and Information</li>
<li>Cooperation among Cooperatives</li>
<li>Concern for Community</li>
</ul>
</blockquote>
<p>And as you can see we do our own summary of the seven cooperative principles; i think we decided <a href="http://www.ncba.coop/"><abbr title="National Cooperative Business Association">NCBA</abbr></a> had our favorite restatement of the seven cooperative principles but their <a href="http://www.ncba.coop/about-us/organization/7-cooperative-principles" rel="nofollow">link is broken</a>.</p>
</li> </div>
</div>
</div>
https://data.agaric.com/search-values#commentsnotesBenjamin MelançonMauricio DinarteMichele MettsAgaric.comAgaricBufferPalante TechRed HatSlackmission statementprinciplespurposevaluesin progressThu, 30 Nov 2017 17:38:58 +0000Benjamin Melançon3978 at https://data.agaric.comFeedback on private, secure cloud storage / backup given to Least Authority
https://data.agaric.com/feedback-private-secure-cloud-storage-backup-given-least-authority
<div class="field field-type-text field-field-description">
<div class="field-items">
<div class="field-item odd">
<p>The convenience (can actually be used) and security balance is the real magic in this space. For example, i am at this moment fairly afraid that i've forgotten my SpiderOak passphrase and lost the backup piece of paper. On my ToDo list for months has been check if i can still access my data and then re-up the subscription. I own my failings, but i suspect other humans share them. Perhaps tiers of data security in one service could be an answer? One tier, the lowest, can be recovered with a password reset to e-mail, so the private key actually stored somewhere with you. Another tier, in the middle, could allow a shorter passphrase that is used frequently (and so actually remembered) with a backup key that is stored locally, encouraged to be printed, and even (for the many of us who are printer free) temporarily transmitted securely to your facilities and printed and sent by US mail to the user. The final tier is for the highest security and people who know they can hold secrets.</p>
</div>
</div>
</div>
https://data.agaric.com/feedback-private-secure-cloud-storage-backup-given-least-authority#commentsnoteBenjamin MelançonLeast AuthoritySpiderOakbackupsecurityThu, 21 Sep 2017 17:48:06 +0000Benjamin Melançon3975 at https://data.agaric.comTime Tracking and Hours Reports in GitLab with GTT
https://data.agaric.com/time-tracking-and-hours-reports-gitlab-gtt
<div class="field field-type-text field-field-description">
<div class="field-items">
<div class="field-item odd">
<p>GitLab has time tracking (caveat: Unfortunately this is the Enterprise Edition, not the fully Free Software Community Edition). See:</p>
<ul>
<li><a href="https://about.gitlab.com/features/time-tracking/" title="https://about.gitlab.com/features/time-tracking/">https://about.gitlab.com/features/time-tracking/</a></li>
<li><a href="https://gitlab.com/help/workflow/time_tracking.md" title="https://gitlab.com/help/workflow/time_tracking.md">https://gitlab.com/help/workflow/time_tracking.md</a></li>
<li><a href="https://docs.gitlab.com/ee/workflow/time_tracking.html" title="https://docs.gitlab.com/ee/workflow/time_tracking.html">https://docs.gitlab.com/ee/workflow/time_tracking.html</a></li>
</ul>
<p>What it doesn't have is any evident way to see, in a reasonable overview, this time that's been tracked.</p>
<p>I got no responses asking this in #gitlab on IRC: Is there any UI for seeing tracked time by person? I can't find it (or any project overview of time tracked) and it's not documented if there is. As a fallback, is there a way to export this time estimate and tracked information? I'm on GitLab.com but we might go self-hosted at some point, so i'm interested on info about both. <a href="https://gitlab.com/gitlab-org/gitlab-ee/issues/1228" title="https://gitlab.com/gitlab-org/gitlab-ee/issues/1228">https://gitlab.com/gitlab-org/gitlab-ee/issues/1228</a> didn't have much.</p>
<p>Never did find the documentation for the API of getting tracked time. But i found an awesome tool that makes full use of that API:</p>
<p><a href="https://github.com/kriskbx/gitlab-time-tracker" title="https://github.com/kriskbx/gitlab-time-tracker">https://github.com/kriskbx/gitlab-time-tracker</a></p>
<h3>Installation</h3>
<p>Installing that command line wonder was pretty easy.</p>
<p>Upgraded Node on my system with: <a href="https://nodejs.org/en/download/package-manager/#debian-and-ubuntu-based-linux-distributions" title="https://nodejs.org/en/download/package-manager/#debian-and-ubuntu-based-linux-distributions">https://nodejs.org/en/download/package-manager/#debian-and-ubuntu-based-linux-distributions</a></p>
<p>Installed Yarn per this: <a href="https://yarnpkg.com/en/docs/install#linux" title="https://yarnpkg.com/en/docs/install#linux">https://yarnpkg.com/en/docs/install#linux</a></p>
<p>And then followed the installation instructions: <a href="https://github.com/kriskbx/gitlab-time-tracker#installation" title="https://github.com/kriskbx/gitlab-time-tracker#installation">https://github.com/kriskbx/gitlab-time-tracker#installation</a></p>
<h3>Usage</h3>
<p><code>gtt report "uc-davis/patient-hm-brain"</code></p>
<p><img src="http://data.agaric.com/sites/default/files/raw_files/gtt-output.png" /></p>
<h3>Project-specific configuration</h3>
<p>In a <code>.gtt.yml</code> in the root of your project directory you can define the project that gtt should use so you don't have to type it each time, along with other options you want for the project. For instance:</p>
<pre>
project: nichq/nichq-community
showWithoutTimes: true
closed: true
query:
- issues
report:
- stats
- issues
- records
</pre><p>Here we have set the project (its path on GitLab.com), that we want it to show issues that do not have times (so we can see what we've estimated), to include closed issues (so we get the full time count), and to not include merge requests in queries or reports because we track all time on issues.</p>
<h3>More usage examples</h3>
<p>These examples require the project-specific configuration—at least the project being set—by a file like the one shown above.</p>
<h4>View only a single sprint (milestone)</h4>
<p><code>gtt report --milestone="Sprint Basinga"</code></p>
<h4>Output a PDF</h4>
<p><code>gtt report --milestone="Sprint Basinga" -o pdf -l basinga.pdf</code></p>
<h4>Output CSV files</h4>
<p><code>gtt report -o csv -l nichq-community-time-2017-12-08.csv</code></p>
<p>Different CSV files will be created for each section of the report, with the command above for example resulting in:</p>
<pre>
nichq-community-time-2017-12-08.issues.csv
nichq-community-time-2017-12-08.records.csv
nichq-community-time-2017-12-08.stats.csv
</pre><h4>Get time worked for a particular user for a given time period</h4>
<p><code>gtt report -u mlncn -f 2018-01-01 -t 2018-02-01</code></p>
</div>
</div>
</div>
<div class="field field-type-text field-field-searchedwords">
<div class="field-label">Searched words: </div>
<div class="field-items">
<div class="field-item odd">
GitLab timetracking output report
reporting estimated time
time spent
time worked </div>
</div>
</div>
<div class="field field-type-filefield field-field-file">
<div class="field-items">
<div class="field-item odd">
<div class="field-label-inline-first">
File: </div>
<div class="filefield-file"><img class="filefield-icon field-icon-image-png" alt="image/png icon" src="https://data.agaric.com/sites/all/modules/filefield/icons/image-x-generic.png" /><a href="https://data.agaric.com/sites/default/files/raw_files/gtt-output.png" type="image/png; length=42729">gtt-output.png</a></div> </div>
</div>
</div>
https://data.agaric.com/time-tracking-and-hours-reports-gitlab-gtt#commentsHow toBenjamin MelançonDrutopiaAgaricestimationtimetime trackingin progressTue, 05 Sep 2017 10:52:25 +0000Benjamin Melançon3974 at https://data.agaric.comCreating nicely formatted PDFs from Markdown files with Atom editor
https://data.agaric.com/creating-nicely-formatted-pdfs-from-markdown-files-atom-editor
<div class="field field-type-text field-field-description">
<div class="field-items">
<div class="field-item odd">
<ul>
<li><a href="https://atom.io/">Atom</a></li>
<li>Make sure Atom's core <a href="https://github.com/atom/markdown-preview">Markdown Preview</a> package is enabled</li>
<li><a href="https://atom.io/packages/markdown-pdf">Markdown to PDF for Atom</a></li>
<li><a href="https://atom.io/packages/paste-table">paste-table for Atom</a></li>
<li><a href="https://www.libreoffice.org/discover/calc/">LibreOffice Calc</a></li>
<li>(Optional) <a href="https://atom.io/packages/vim-mode-plus">vim-mode-plus for Atom</a></li>
<li>(Optional) Make sure Atom's core autosave is enabled.</li>
</ul>
<p>The current approach to having our proposals in version control is to generate PDFs from Markdown files. (This is much simpler to set up and use than our previous <a href="http://www.latex-project.org/">LaTeX</a> approach, at the cost of losing some formatting control which we weren't using anyway.)</p>
<p>After <a href="https://atom.io/">installing Atom</a>, install the above-referenced packages with:</p>
<p><code>apm install markdown-pdf paste-table vim-mode-plus</code></p>
<p>Or (if just starting with Atom) <a href="https://gitlab.com/mlncn/atom">copy ben's Atom setup</a>.</p>
</div>
</div>
</div>
<div class="field field-type-text field-field-searchedwords">
<div class="field-label">Searched words: </div>
<div class="field-items">
<div class="field-item odd">
markdown preview
markdown to PDF </div>
</div>
</div>
https://data.agaric.com/creating-nicely-formatted-pdfs-from-markdown-files-atom-editor#commentsHow toBenjamin MelançonAtomAgaricmarkdownmarkupPDFPortable Document Format (PDF)text editordoneWed, 24 May 2017 14:38:53 +0000Benjamin Melançon3968 at https://data.agaric.comRemoving double spaces in usernames directly in the SQL
https://data.agaric.com/removing-double-spaces-usernames-directly-sql
<div class="field field-type-text field-field-description">
<div class="field-items">
<div class="field-item odd">
<p>A client using the <a href="https://www.drupal.org/project/bulk_invite">Bulk invite</a> module (by Agaric's David Valdez) had invited hundreds of users with slightly malformed usernames— two spaces between first and last name when there should only be one.</p>
<p>Note that you need to do the change both in the users_field_data table and the users_field_revision table— and you need to clear caches when you're done to see the change on user edit pages, which is where it matters.</p>
<div class="codeblock"><code>drush sqlc<br />UPDATE users_field_data SET name = REPLACE(name,' ',' ');</code></div>
<p>Check for the response! For example, the first time i ran this it returned:</p>
<p><code>ERROR 1062 (23000): Duplicate entry 'John Doe-en' for key 'user__name'</code></p>
<p>This was because the same name was there twice (once with a single space and once with a double space) associated with different e-mail addresses (but almost certainly the same person). Rather than make the decision of which e-mail address should be used for this user, it was easiest to rename the existing username for the second address:</p>
<p><code>UPDATE users_field_data SET name = REPLACE(name,'John Doe','JohnDoe');</code></p>
<p>And then the original command could complete, like this:</p>
<div class="codeblock"><code>mysql> UPDATE users_field_data SET name = REPLACE(name,' ',' ');<br />Query OK, 243 rows affected (0.02 sec)<br />Rows matched: 497 Changed: 243 Warnings: 0</code></div>
<p>And then the users_field_revision table, in our case still with the extra step:</p>
<div class="codeblock"><code>UPDATE users_field_revision SET name = REPLACE(name,'John Doe','JohnDoe');<br />Query OK, 1 row affected (0.01 sec)<br />Rows matched: 798 Changed: 1 Warnings: 0
<p>mysql> UPDATE users_field_revision SET name = REPLACE(name,' ',' ');<br />Query OK, 250 rows affected (0.01 sec)<br />Rows matched: 798 Changed: 250 Warnings: 0</p></code></div>
<p>Then exit MySQL/MariaDB/whathaveyou and <strong>clear caches</strong>:</p>
<div class="codeblock"><code>../vendor/bin/drush cr</code></div>
</div>
</div>
</div>
<div class="field field-type-text field-field-searchedwords">
<div class="field-label">Searched words: </div>
<div class="field-items">
<div class="field-item odd">
SQL search for double space
MySQL find and replace doublespace in database field </div>
</div>
</div>
https://data.agaric.com/removing-double-spaces-usernames-directly-sql#commentsHow toBenjamin MelançonTeachers with GUTSAgaricSQLdoneFri, 05 May 2017 11:22:29 +0000Benjamin Melançon3965 at https://data.agaric.comSend gitlab.com commit message to IRC
https://data.agaric.com/send-gitlabcom-commit-message-irc
<div class="field field-type-text field-field-description">
<div class="field-items">
<div class="field-item odd">
<p>There is sadly no default way to do this directly from GitLab.com— but there's a pretty simple way, with Bishop:</p>
<p><a href="https://github.com/ta/bishop" title="https://github.com/ta/bishop">https://github.com/ta/bishop</a></p>
<p>Install Heroku locally. These instructions from <a href="https://devcenter.heroku.com/articles/getting-started-with-ruby#set-up" title="https://devcenter.heroku.com/articles/getting-started-with-ruby#set-up">https://devcenter.heroku.com/articles/getting-started-with-ruby#set-up</a> worked great for me:</p>
<div class="codeblock"><code>sudo add-apt-repository "deb <a href="https://cli-assets.heroku.com/branches/stable/apt" title="https://cli-assets.heroku.com/branches/stable/apt">https://cli-assets.heroku.com/branches/stable/apt</a> ./"<br />curl -L <a href="https://cli-assets.heroku.com/apt/release.key" title="https://cli-assets.heroku.com/apt/release.key">https://cli-assets.heroku.com/apt/release.key</a> | sudo apt-key add -<br />sudo apt-get update<br />sudo apt-get install heroku</code></div>
<p>Then:</p>
<div class="codeblock"><code>heroku apps:create bishop-example --stack cedar</code></div>
<p>Results in:</p>
<p><em>Creating ⬢ bishop-example... done, stack is cedar-14<br />
<a href="https://bishop-example.herokuapp.com/" title="https://bishop-example.herokuapp.com/">https://bishop-example.herokuapp.com/</a> | https://git.heroku.com/bishop-example.git</em></p>
<p><code>heroku config:add BISHOP_API_KEY=dc83Pzn2foy4039 BISHOP_SERVER=irc.freenode.net BISHOP_CHANNELS=#example</code></p>
<p><em>Setting BISHOP_API_KEY, BISHOP_SERVER, BISHOP_CHANNELS and restarting ⬢ bishop-example... done, v3</em></p>
<p>BISHOP_API_KEY: dc83Pzn2foy4039<br />
BISHOP_CHANNELS: #example<br />
BISHOP_SERVER: irc.freenode.net<br />
</p>
<p><code>git push heroku master</code></p>
<p>(Note: The heroku app adds heroku as a remote repository all on its own.)</p>
<p>And, this is critical:</p>
<p><code>heroku config:add BISHOP_GITLAB_HOOK_CHANNELS=#example</code></p>
<p>We hacked it to rename the bot to bishop-example<br />
2<br />
3 # Changes to be committed:<br />
4 # modified: lib/bishop/bot.rb</p>
<p>git push heroku</p>
<p>Now, to a GitLab repository, under settings/integrations, add a webhook:</p>
<p><a href="https://bishop-example.herokuapp.com/hooks/gitlab/dc83Pzn2foy4039" title="https://bishop-example.herokuapp.com/hooks/gitlab/dc83Pzn2foy4039">https://bishop-example.herokuapp.com/hooks/gitlab/dc83Pzn2foy4039</a></p>
</div>
</div>
</div>
https://data.agaric.com/send-gitlabcom-commit-message-irc#commentsHow toBenjamin MelançonBishopGitlabIRCFri, 10 Mar 2017 03:42:54 +0000Benjamin Melançon3962 at https://data.agaric.comDate field date-only migration from Drupal 7 to Drupal 8
https://data.agaric.com/date-field-date-only-migration-from-drupal-7-drupal-8
<div class="field field-type-text field-field-description">
<div class="field-items">
<div class="field-item odd">
<p>After we did the upgrade of a Drupal 7 site to Drupal 8, a date field which had been taking only the date portion, and no time portion, was now configured to take both the date and the time. Moreover, the migration wasn't working.</p>
<p>We changed the configuration from datetime to date</p>
<p>Here's the relevant part of the diff for config/default/field.storage.node.field_pub_date.yml</p>
<pre>
field_name: field_pub_date
entity_type: node
type: datetime
settings:
- datetime_type: datetime
+ datetime_type: date
module: datetime
locked: false
cardinality: 1
</pre><p>Note that changing this configuration requires a re-install of the site— storage settings can't be changed in an operating site.</p>
<p>The date was actually imported but, as shown by a "SELECT field_pub_date_value, entity_id FROM node__field_pub_date;" query, in the format "2016-10-10 00:00:00". That caused it to not display, and when editing, to show the field as blank. Saving the node after filling out the blanked field showed that it was saved as "2016-10-10" in normal operation.</p>
<p>In config/default/migrate_plus.migration.upgrade_d7_node_article.yml changing the line the Drupal upgrade had left us, "field_pub_date: field_pub_date" under the process directive, to the following instead, fixed the date migration:</p>
<pre>
process:
field_pub_date:
plugin: iterator
source: field_pub_date
process:
value:
plugin: substr
source: value
start: 0
length: 10
</pre> </div>
</div>
</div>
<div class="field field-type-text field-field-searchedwords">
<div class="field-label">Searched words: </div>
<div class="field-items">
<div class="field-item odd">
drupal 8 date migrate
drupal 8 migrate datetime field not migrated
drupal 7 to drupal 8 "date" migration
The input value must be a string.
</div>
</div>
</div>
https://data.agaric.com/date-field-date-only-migration-from-drupal-7-drupal-8#commentsnoteBenjamin MelançonDrupal 8MigrateAgaricPortsidecontent migrationMon, 06 Feb 2017 18:51:04 +0000Benjamin Melançon3960 at https://data.agaric.comUsing JavaScript in Behat tests (manual steps for installing, running)
https://data.agaric.com/using-javascript-behat-tests-manual-steps-installing-running
<div class="field field-type-text field-field-description">
<div class="field-items">
<div class="field-item odd">
<p>In virtual machine:</p>
<pre>
cd ~
# Go to <a href="http://phantomjs.org/download.html" title="http://phantomjs.org/download.html">http://phantomjs.org/download.html</a> to see the latest available.
wget <a href="https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2" title="https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2">https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2</a>
tar -xjf phantomjs-2.1.1-linux-x86_64.tar.bz2
# phantomjs --webdriver=4444
/home/vagrant/phantomjs-2.1.1-linux-x86_64/bin/phantomjs --webdriver=4444
</pre><p>Now you can test @javascript tagged Behat tests.</p>
<p>Until the above is automated, exclude JavaScript-requiring tests by default.</p>
<p>In behat.yml:</p>
<pre>
default:
gherkin:
filters:
tags: ~@javascript
</pre><p>Run with:</p>
<pre>
behat --tags=javascript
</pre><p>References:</p>
<p><a href="http://docs.behat.org/en/v3.0/guides/6.profiles.html" title="http://docs.behat.org/en/v3.0/guides/6.profiles.html">http://docs.behat.org/en/v3.0/guides/6.profiles.html</a></p>
<p><a href="http://jaffamonkey.com/using-phantomjs-with-behat/" title="http://jaffamonkey.com/using-phantomjs-with-behat/">http://jaffamonkey.com/using-phantomjs-with-behat/</a></p>
</div>
</div>
</div>
<div class="field field-type-text field-field-searchedwords">
<div class="field-label">Searched words: </div>
<div class="field-items">
<div class="field-item odd">
behat drupal extension contextual links edit
debian extract tar.bz2
behat.yml exclude by default </div>
</div>
</div>
https://data.agaric.com/using-javascript-behat-tests-manual-steps-installing-running#commentsHow toBenjamin MelançonBehatbehat testingJavaScriptin progressMon, 14 Nov 2016 15:25:40 +0000Benjamin Melançon3955 at https://data.agaric.comEasily add content with update hooks: use default content module exports to create content that needs to be in sync with configuration
https://data.agaric.com/easily-add-content-update-hooks-use-default-content-module-exports-create-content-needs-be-sync-conf
<div class="field field-type-text field-field-description">
<div class="field-items">
<div class="field-item odd">
<p>An approach for keeping content that is added as part of development synchronized with test and production environments is to use the <a href="https://drupal.org/project/default_content">Default Content</a> module to export the content. It's built for the content to be exported to an installation profile's 'content' folder, and then the module, if enabled, automatically brings the content in when the site is installed. Presuming that reinstalling the site would be a drastic step for getting one block's content (aside: we do find it useful to use installation profiles with default content for automated testing and initial development), it's also possible to import the content one item at a time, such as in an update hook, with the below code in your example.install or example.profile:</p>
<p><em>Updated to support taxonomy terms import!</em></p>
<div class="codeblock"><code><span style="color: #000000"><span style="color: #0000BB"><?php<br /></span><span style="color: #FF8000">/**<br /> * Import a piece of content exported by default content module.<br /> */<br /></span><span style="color: #007700">function </span><span style="color: #0000BB">example_import_default_content</span><span style="color: #007700">(</span><span style="color: #0000BB">$path_to_content_json</span><span style="color: #007700">) {<br /> list(</span><span style="color: #0000BB">$entity_type_id</span><span style="color: #007700">, </span><span style="color: #0000BB">$filename</span><span style="color: #007700">) = </span><span style="color: #0000BB">explode</span><span style="color: #007700">(</span><span style="color: #DD0000">'/'</span><span style="color: #007700">, </span><span style="color: #0000BB">$path_to_content_json</span><span style="color: #007700">);<br /> </span><span style="color: #0000BB">$p </span><span style="color: #007700">= </span><span style="color: #0000BB">drupal_get_path</span><span style="color: #007700">(</span><span style="color: #DD0000">'profile'</span><span style="color: #007700">, </span><span style="color: #DD0000">'guts'</span><span style="color: #007700">);<br /> </span><span style="color: #0000BB">$encoded_content </span><span style="color: #007700">= </span><span style="color: #0000BB">file_get_contents</span><span style="color: #007700">(</span><span style="color: #0000BB">$p </span><span style="color: #007700">. </span><span style="color: #DD0000">'/content/' </span><span style="color: #007700">. </span><span style="color: #0000BB">$path_to_content_json</span><span style="color: #007700">);<br /> </span><span style="color: #0000BB">$serializer </span><span style="color: #007700">= \</span><span style="color: #0000BB">Drupal</span><span style="color: #007700">::</span><span style="color: #0000BB">service</span><span style="color: #007700">(</span><span style="color: #DD0000">'serializer'</span><span style="color: #007700">);<br /> </span><span style="color: #0000BB">$content </span><span style="color: #007700">= </span><span style="color: #0000BB">$serializer</span><span style="color: #007700">-></span><span style="color: #0000BB">decode</span><span style="color: #007700">(</span><span style="color: #0000BB">$encoded_content</span><span style="color: #007700">, </span><span style="color: #DD0000">'hal_json'</span><span style="color: #007700">);<br /> global </span><span style="color: #0000BB">$base_url</span><span style="color: #007700">;<br /> </span><span style="color: #0000BB">$url </span><span style="color: #007700">= </span><span style="color: #0000BB">$base_url </span><span style="color: #007700">. </span><span style="color: #0000BB">base_path</span><span style="color: #007700">();<br /> </span><span style="color: #0000BB">$content</span><span style="color: #007700">[</span><span style="color: #DD0000">'_links'</span><span style="color: #007700">][</span><span style="color: #DD0000">'type'</span><span style="color: #007700">][</span><span style="color: #DD0000">'href'</span><span style="color: #007700">] = </span><span style="color: #0000BB">str_replace</span><span style="color: #007700">(</span><span style="color: #DD0000">'http://drupal.org/'</span><span style="color: #007700">, </span><span style="color: #0000BB">$url</span><span style="color: #007700">, </span><span style="color: #0000BB">$content</span><span style="color: #007700">[</span><span style="color: #DD0000">'_links'</span><span style="color: #007700">][</span><span style="color: #DD0000">'type'</span><span style="color: #007700">][</span><span style="color: #DD0000">'href'</span><span style="color: #007700">]);<br /> </span><span style="color: #0000BB">$contents </span><span style="color: #007700">= </span><span style="color: #0000BB">$serializer</span><span style="color: #007700">-></span><span style="color: #0000BB">encode</span><span style="color: #007700">(</span><span style="color: #0000BB">$content</span><span style="color: #007700">, </span><span style="color: #DD0000">'hal_json'</span><span style="color: #007700">);<br /> </span><span style="color: #FF8000">// The path for the taxonomy term class is different.<br /> </span><span style="color: #007700">if (</span><span style="color: #0000BB">$entity_type_id </span><span style="color: #007700">== </span><span style="color: #DD0000">'taxonomy_term'</span><span style="color: #007700">) {<br /> </span><span style="color: #0000BB">$class </span><span style="color: #007700">= </span><span style="color: #DD0000">'Drupal\taxonomy\Entity\Term'</span><span style="color: #007700">;<br /> } else {<br /> </span><span style="color: #0000BB">$class </span><span style="color: #007700">= </span><span style="color: #DD0000">'Drupal\\' </span><span style="color: #007700">. </span><span style="color: #0000BB">$entity_type_id </span><span style="color: #007700">. </span><span style="color: #DD0000">'\Entity\\' </span><span style="color: #007700">. </span><span style="color: #0000BB">str_replace</span><span style="color: #007700">(</span><span style="color: #DD0000">' '</span><span style="color: #007700">, </span><span style="color: #DD0000">''</span><span style="color: #007700">, </span><span style="color: #0000BB">ucwords</span><span style="color: #007700">(</span><span style="color: #0000BB">str_replace</span><span style="color: #007700">(</span><span style="color: #DD0000">'_'</span><span style="color: #007700">, </span><span style="color: #DD0000">' '</span><span style="color: #007700">, </span><span style="color: #0000BB">$entity_type_id</span><span style="color: #007700">)));<br /> }<br /> </span><span style="color: #0000BB">$entity </span><span style="color: #007700">= </span><span style="color: #0000BB">$serializer</span><span style="color: #007700">-></span><span style="color: #0000BB">deserialize</span><span style="color: #007700">(</span><span style="color: #0000BB">$contents</span><span style="color: #007700">, </span><span style="color: #0000BB">$class</span><span style="color: #007700">, </span><span style="color: #DD0000">'hal_json'</span><span style="color: #007700">, array(</span><span style="color: #DD0000">'request_method' </span><span style="color: #007700">=> </span><span style="color: #DD0000">'POST'</span><span style="color: #007700">));<br /> </span><span style="color: #0000BB">$entity</span><span style="color: #007700">-></span><span style="color: #0000BB">enforceIsNew</span><span style="color: #007700">(</span><span style="color: #0000BB">TRUE</span><span style="color: #007700">);<br /> </span><span style="color: #0000BB">$entity</span><span style="color: #007700">-></span><span style="color: #0000BB">save</span><span style="color: #007700">();<br />}<br /></span><span style="color: #0000BB">?></span></span></code></div>
<p>Export a custom block with an ID of 8:</p>
<p><code>drush dcer block_content 8</code></p>
<p>And used in your example.install file:</p>
<div class="codeblock"><code><span style="color: #000000"><span style="color: #0000BB"><?php<br /></span><span style="color: #FF8000">/**<br /> * Add the footer block content.<br /> *<br /> * Implements hook_update_N().<br /> */<br /></span><span style="color: #007700">function </span><span style="color: #0000BB">example_update_8001</span><span style="color: #007700">() {<br /> </span><span style="color: #0000BB">example_import_default_content</span><span style="color: #007700">(</span><span style="color: #DD0000">'block_content/136efd63-021e-42ea-8202-8b97305cc07f.json'</span><span style="color: #007700">);<br />}<br /></span><span style="color: #0000BB">?></span></span></code></div>
<p>See also <a href="/drupal-8-default-content-agaric-way">Drupal 8 default content notes</a>.</p>
</div>
</div>
</div>
<div class="field field-type-text field-field-searchedwords">
<div class="field-label">Searched words: </div>
<div class="field-items">
<div class="field-item odd">
programmatically make nodes, taxonomy terms, menu items, other content </div>
</div>
</div>
https://data.agaric.com/easily-add-content-update-hooks-use-default-content-module-exports-create-content-needs-be-sync-conf#commentsHow toBenjamin MelançonDrupal 8AgariccontentexportimportdoneMon, 19 Sep 2016 19:17:55 +0000Benjamin Melançon3954 at https://data.agaric.com