<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>issue tracking Archives - Alexandros Georgiou</title>
	<atom:link href="https://www.alexgeorgiou.gr/tag/issue-tracking/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.alexgeorgiou.gr/tag/issue-tracking/</link>
	<description>Balancing brackets for a living</description>
	<lastBuildDate>Mon, 22 Apr 2024 09:25:48 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://www.alexgeorgiou.gr/wp-content/uploads/2021/07/cropped-alexgeorgiou-icon-32x32.png</url>
	<title>issue tracking Archives - Alexandros Georgiou</title>
	<link>https://www.alexgeorgiou.gr/tag/issue-tracking/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>How to migrate trac MySQL-based project from trac 1.0.12 to trac 0.11.7</title>
		<link>https://www.alexgeorgiou.gr/migrate-trac-1-0-12-to-0-11-7/</link>
					<comments>https://www.alexgeorgiou.gr/migrate-trac-1-0-12-to-0-11-7/#respond</comments>
		
		<dc:creator><![CDATA[alexg]]></dc:creator>
		<pubDate>Mon, 13 Mar 2017 20:25:14 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[backup]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[downgrade]]></category>
		<category><![CDATA[issue tracking]]></category>
		<category><![CDATA[mysqldump]]></category>
		<category><![CDATA[project management]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[trac]]></category>
		<guid isPermaLink="false">http://www.alexgeorgiou.gr/?p=199</guid>

					<description><![CDATA[<p>How to migrate trac project from 1.0.12 to a 0.11.7 installation if your project is MySQL based.</p>
<p>The post <a href="https://www.alexgeorgiou.gr/migrate-trac-1-0-12-to-0-11-7/">How to migrate trac MySQL-based project from trac 1.0.12 to trac 0.11.7</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>In a world dominated by <a href="https://www.atlassian.com/software/jira" target="_blank" rel="noopener noreferrer"><code>JIRA</code></a>, some still dare to use <a href="https://trac.edgewall.org/" target="_blank" rel="noopener noreferrer"><code>trac</code></a>&#8230; Here&#8217;s how to migrate <code>trac</code> to an earlier version, assuming this was a good idea, which of course it is not!</p>
<h2>Versions</h2>
<p>On my Ubuntu 16 installation (let&#8217;s call it <code>example1.com</code>) I have a project on this version of <code>trac</code>:</p>
<pre>$ lsb_release  -d
Description:    Ubuntu 16.10
$ tracd --version
tracd 1.0.12</pre>
<p>I had good(-ish) reasons to migrate the entire project to a copy on an Ubuntu 10 machine.</p>
<pre>$ lsb_release -d
Description:    Ubuntu 10.04.4 LTS</pre>
<h2>Installing trac</h2>
<p>These are the resources that you need to be aware of:</p>
<ul>
<li><a href="https://trac.edgewall.org/wiki/TracOnUbuntu" target="_blank" rel="noopener noreferrer">https://trac.edgewall.org/wiki/TracOnUbuntu</a></li>
<li><a href="https://trac.edgewall.org/wiki/MySqlDb" target="_blank" rel="noopener noreferrer">https://trac.edgewall.org/wiki/MySqlDb</a></li>
</ul>
<p>I first installed <code>trac</code> via the <code>old-releases.ubuntu.com</code> repository.</p>
<pre>$ sudo apt-get install trac</pre>
<p>This installed an earlier version than the one I had.</p>
<pre class="wiki">$ tracd --version
tracd 0.11.7</pre>
<h2>Setting up the new (old) trac</h2>
<p>Rather than upgrading the entire system with <code>do-release-upgrade</code>, I decided to work with this version.</p>
<p>You will need the <code>python-mysqldb</code> module on <code>example2.com</code> to access a MySQL database. If you&#8217;re using PostgreSQL the procedure <em>should</em> be similar. YMMV.</p>
<pre class="wiki">$ sudo apt-get install python-mysqldb</pre>
<p>First, copy the assets of the project environment. This is a directory tree that you can copy over using <code>rsync</code>.</p>
<pre class="wiki">rsync -r example1.com:/path-to-trac-env example2.com:/path-to-trac-env</pre>
<p>For simplicity we&#8217;ll keep everything the same: file directories, database name and database credentials, although you could change these. Your database settings are in the <code>/path-to-trac-env/conf/trac.ini</code> file. You want the database variable under the <code>[trac]</code> section, which should look something like:</p>
<pre>[trac]

database = mysql://tracuser:tracpassword@localhost:3306/trac-env</pre>
<p>You will want to create an empty MySQL database where your project will live. You will need the MySQL client on <code>example2.com</code>, so if you don&#8217;t have it, install it with:</p>
<pre>sudo apt-get install mysql-client</pre>
<p>You will then want to login as root</p>
<pre>mysql -u root -p</pre>
<p>and create the database, (using the <code>utf8_bin</code> collation)</p>
<pre class="wiki">CREATE DATABASE `trac-env` DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;</pre>
<p>and finally create the user:</p>
<pre class="wiki">GRANT ALL ON `trac-env`.* TO tracuser@localhost IDENTIFIED BY 'tracpassword';</pre>
<p>Exit the MySQL client with <code>Ctrl-D</code> and import a standard SQL dump of your database from <code>example1.com</code>. For instance, if you like one-liners, you might do this on <code>example2.com</code>:</p>
<pre class="wiki">ssh example1.com "mysqldump -u tracuser -ptracpassword --single-transaction trac-env | gzip -9" | zcat | mysql -u tracuser -ptracpassword trac-env</pre>
<h2>Nasty hack FTW</h2>
<p>Now start <code>tracd</code> and visit the installation via your web browser. You should see an error like this:</p>
<pre class="wiki"> Trac detected an internal error:

ValueError: timestamp out of range for platform time_t</pre>
<p>This is because all timestamps in this newer version of <code>trac</code> are in microseconds, rather than seconds. Here is <a href="https://trac.edgewall.org/ticket/9314">a (somewhat) relevant ticket</a>.</p>
<p>I went ahead and hacked the DB thusly:</p>
<pre class="wiki">update ignore attachment set time = floor( time / 10000000);
update ignore auth_cookie set time = floor( time / 10000000);
update ignore revision set time = floor( time / 10000000);
update ignore ticket set time = floor( time / 10000000);
update ignore ticket set changetime = floor( changetime / 10000000);
update ignore ticket_change set time = floor( time / 10000000);
update ignore version set time = floor( time / 10000000);
update ignore wiki set time = floor( time / 10000000);</pre>
<p>These are all the timestamp columns in the DB. Dividing by a million converts millionths of a second to seconds and the <code>floor</code> function makes sure that the result is still an integer.</p>
<p>The <code>ignore</code> argument is there only because I had one single collision in one ticket comment. Needless to say, this is a nasty hack, so don&#8217;t rely on it too much.</p>
<p>But, for my purposes, <strong>&#8220;It Works<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />&#8221;!</strong></p>
<p>The post <a href="https://www.alexgeorgiou.gr/migrate-trac-1-0-12-to-0-11-7/">How to migrate trac MySQL-based project from trac 1.0.12 to trac 0.11.7</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.alexgeorgiou.gr/migrate-trac-1-0-12-to-0-11-7/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to offer subscription downloads and support with WordPress</title>
		<link>https://www.alexgeorgiou.gr/offer-subscription-downloads-support-wordpress/</link>
					<comments>https://www.alexgeorgiou.gr/offer-subscription-downloads-support-wordpress/#respond</comments>
		
		<dc:creator><![CDATA[alexg]]></dc:creator>
		<pubDate>Fri, 15 Jul 2016 07:08:12 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[downloads]]></category>
		<category><![CDATA[filter]]></category>
		<category><![CDATA[issue tracking]]></category>
		<category><![CDATA[membership]]></category>
		<category><![CDATA[subscription]]></category>
		<category><![CDATA[support]]></category>
		<category><![CDATA[wordpress]]></category>
		<guid isPermaLink="false">http://www.alexgeorgiou.gr/?p=103</guid>

					<description><![CDATA[<p>In this article I will show you one way you can create a WordPress site where subscription downloads and support are available only to current subscribers.</p>
<p>The post <a href="https://www.alexgeorgiou.gr/offer-subscription-downloads-support-wordpress/">How to offer subscription downloads and support with WordPress</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>In this article I will show you one way you can create a WordPress site where subscription downloads and support are available only to current subscribers.</p>
<h2>Requirement: Subscription downloads and support</h2>
<p>Some of the least perceptive readers of this blog will wonder, why is this a problem? Just install <a href="https://wordpress.org/plugins/easy-digital-downloads/">Easy Digital Downloads</a> and be ready to go. <em>EDD</em> is an awesome plugin for selling all kinds of digital products, be they graphics, software, books, you name it. If it&#8217;s a file you can sell it, and there&#8217;s a range of plugins for alternative functionality, payment gateways and such.</p>
<p><strong>Read the title again!</strong> What I wanted was not to simply sell some downloads, but to offer a subscription service where said downloads are accessible. I could perhaps have gone with using the licensing extensions of <em>EDD</em>, but I also had the requirement that I wanted to offer restricted access to other content on the site.</p>
<p>The model I was going for is that a paying customer gets access to</p>
<ol>
<li>downloads, and</li>
<li>support,</li>
</ol>
<p>while other people simply have access to a subset of the site&#8217;s content.</p>
<h2>Picking off-the-shelf components</h2>
<p>Now, in WordPressland, subscriptions equals <em><a href="https://wordpress.org/plugins/simple-membership/">Simple Membership</a></em>. So I went ahead and installed that. It can utilize <a href="https://developer.paypal.com/api/nvp-soap/paypal-payments-pro/">PayPal recurring payments</a>, so you can offer a subscription service that renews automatically, unless the subscriber decides to opt-out. This is, for instance, <a href="https://premium.wpmudev.org/terms-of-service/#subs">part of the model of the very successful WPMU DEV site</a>. As a sidenote, I liked how Simple Membership integrates with <a href="http://mailchimp.com/"><em>MailChimp</em></a>, since I&#8217;ll be needing a newsletter feature for my subscribers.</p>
<p>For issue tracking, I decided to go with <em><a href="https://wordpress.org/plugins/software-issue-manager/">Software Issue Manager</a></em>. Unfortunately as of this writing, WordPress does not have as wide <a href="https://wordpress.org/plugins/tags/ticket-system">a selection of free ticket systems</a> as I would have liked to see, but <em>SIM</em> is a good one and is configurable enough to fit my needs. It creates custom post types for Projects (software) and Issues (tickets). This is convenient because it means that these can then be protected with <em>Simple Membership</em>, like all other WordPress content.</p>
<p>For downloads, I chose <em><a href="https://wordpress.org/plugins/download-manager/">Download Manager</a></em>. The free edition offers all kinds of features for providing free downloads, while the premium package lets you build your own digital store. Since I&#8217;m using <em>Simple Membership</em> for billing, I don&#8217;t need the store features. I loved the feature where different versions of the same download are stored under one entity. You can offer downloads to your latest version in a prominent way, and still let the users download previous versions if they want to. There&#8217;s a simple templating system for building your download views.</p>
<p>And that&#8217;s it. Again, the three essential components I ended up with were the free editions of:</p>
<ol>
<li><em><a href="https://wordpress.org/plugins/simple-membership/">Download Manager</a></em> for creating downloads,</li>
<li><em><a href="https://wordpress.org/plugins/software-issue-manager/">Software Issue Manager</a></em> for issue tracking, and</li>
<li><em><a href="https://wordpress.org/plugins/simple-membership/">Simple Membership</a></em> for protecting the above content and for billing.</li>
</ol>
<p>Now my only worry is whether the visitors of my site will be more keen to pay for digital goods than I was :-p</p>
<h2>Glue code</h2>
<p>By using free third-party components I&#8217;ve already packed quite a lot of features into my site without writing any code. Yet!</p>
<p>OK I&#8217;ve had to edit my <em>nginx</em> configuration so that protected downloads are actually protected,</p>
<pre>    location /wp-content/uploads/dlm_uploads {
        deny all;
        return 403;
    }</pre>
<p>but that hardly counts as code. (<em>Apache</em> users are pandered with a ready-made <code>.htaccess</code> file, so they have to do even less than that!)</p>
<h2>Expired subscribers should have no access</h2>
<p>It turns out I did need to write some code. <em>Simple Membership</em> stores its members as WordPress users, with the Subscriber role. When these users have paid, this is tracked by the plugin. When their subscription expires, they remain WordPress users. They lose access to the issue tracker because it is a custom post type and thus directly protected by <em>Simple Membership</em>. But downloads are shortcodes that generate links, and place them into pages that are not protected. And even if we could protect the links or their pages, we don&#8217;t want the subscribers guessing the URLs of new downloads. Users whose subscription has expired should have no access.</p>
<p>Fortunately, <em>Download Manager</em> offers a filter for access to downloads. And <em>Simple Membership</em> offers an easy way to check if the current user&#8217;s subscription has expired. Putting two and two together&#8230;</p>
<pre>// restrict members only downloads if user is logged in but expired
function my_dlm_can_download( $can_download, $download ) {

    $auth = SwpmAuth::get_instance();

    //Check if account is expired.
    if (
        is_user_logged_in() &amp;&amp; 
        $auth-&gt;is_expired_account() &amp;&amp; 
        $download-&gt;is_members_only() ) {
            
            return false;
        }

    return $can_download;
}

add_filter( 'dlm_can_download', 'my_dlm_can_download', 11, 2 );</pre>
<p>I will now let you marvel at the simplicity&#8230;</p>
<p>&nbsp;</p>
<p>The post <a href="https://www.alexgeorgiou.gr/offer-subscription-downloads-support-wordpress/">How to offer subscription downloads and support with WordPress</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.alexgeorgiou.gr/offer-subscription-downloads-support-wordpress/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
