<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Shaheer Sarfaraz</title>
    <description>The latest articles on Forem by Shaheer Sarfaraz (@dakheera47).</description>
    <link>https://forem.com/dakheera47</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F920140%2F5970203e-98c9-42ed-844c-523b5bc47434.jpg</url>
      <title>Forem: Shaheer Sarfaraz</title>
      <link>https://forem.com/dakheera47</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/dakheera47"/>
    <language>en</language>
    <item>
      <title>Saving time by wasting it - The story of AutoClass</title>
      <dc:creator>Shaheer Sarfaraz</dc:creator>
      <pubDate>Fri, 14 Oct 2022 13:08:03 +0000</pubDate>
      <link>https://forem.com/dakheera47/saving-time-by-wasting-it-the-story-of-autoclass-hfa</link>
      <guid>https://forem.com/dakheera47/saving-time-by-wasting-it-the-story-of-autoclass-hfa</guid>
      <description>&lt;h1&gt;
  
  
  The Idea
&lt;/h1&gt;

&lt;p&gt;Because of online lessons during the lockdown, my friends and I thought that getting out of bed at 8:00 a.m. to sit in front of a screen with a monotonous teacher teaching an unimportant topic was boring.&lt;/p&gt;

&lt;p&gt;This was about to change since it occurred to me that classes typically start at the same time each day. The starting time of a lesson is scheduled in advance and doesn't change much from day to day. This means that instead of waking up at 8 am to take my class, the computer would know it's 8 am, know it's time for a class, and join that class's Zoom meeting code.&lt;/p&gt;

&lt;p&gt;The heart of the program does just this. However, some changes still needed to be made to make AutoClass an actually easy (read: usable) program for me and my classmates. The most important of these changes was ensuring you joined the meeting even if something unexpected happened.&lt;/p&gt;

&lt;p&gt;Of course, teachers are also humans, and they can't always start their classes strictly at the chime of the hour, so that's a good starting point for where to start handling these edge cases. Technically, the program went through quite a few stages since sometimes, I'd wake up at 12:00 and realize the program failed to join any classes before this time. I'd trace down what went wrong and fix it in the next update.&lt;/p&gt;

&lt;p&gt;Over time, I developed AutoClass into utterly impenetrable software that could handle the most extreme edge circumstances. An example is when the teacher forgot to start the lesson until much later than the scheduled time or when the teacher removed me (read: my computer) from the classroom.&lt;/p&gt;

&lt;p&gt;All of this combined meant that regular online classes merely served as a testbed for new features and improvements I'd implemented in AutoClass, not as a source of academic learning. My classmates and I started to push the limits of AutoClass and the school's management once the software had proven reliable to a certain extent.&lt;/p&gt;

&lt;p&gt;Since I had spent the better part of the previous year working on AutoClass, and dare I say I was really proud of it, I knew I had to include it with my uni apps. However, this presented another problem because our school doesn't have a strictly separate admin and counseling department. This means that I can't write about AutoClass without also revealing that I wasn't taking any of my classes. I had to work around this by entrusting my work to only one of the councilors I trusted a little more to not open my secret, at least until I passed the school.&lt;/p&gt;

&lt;p&gt;Development continued until the school shifted to a hybrid approach where some classes were on-campus, with the option to take them online if you so preferred. I would leave AutoClass running at home even when attending the school in person since I wasn't ready to stop the constant progress and improvement. Hence, there was a time when a person named "Shaheer Sarfaraz" was present in a class in person and online. This is, of course, extremely easy for any half-competent admin department to identify as an issue. Thankfully for us, this wasn't an issue :).&lt;/p&gt;

&lt;p&gt;There's still the fact that my classmates are pretty observant, and so there were a few times when some of them called me out, saying, "wait, you're here in person, I swear I saw you in the online class as well." I was forced to make something up to ensure my "secret" wasn't discovered. I doubt that anyone was buying my shenanigans, however.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Consequences
&lt;/h1&gt;

&lt;p&gt;I've paraded that we were skipping classes left, right, and center as wholly positive, which was in the short term, but the long term was soon approaching. Mock exams took place in our school before the A Levels exams, and my entire friend group knew absolutely nothing. Not even what we had to know.&lt;/p&gt;

&lt;p&gt;Because we weren't taking any classes, our academic performance declined sharply. We were unable to approach our teachers since, in their eyes, given our exemplary attendance record, we had to be familiar with every subject at the very least. This couldn't be farther from the truth, so we knew we had to study by scraping together all the Indian Youtube Channels to help us out.&lt;/p&gt;

&lt;p&gt;Students started blaming AutoClass as a source of their failures. This was amusing because they knew the risks of missing practically all classes in 6 months, yet they blamed my program. Thankfully, at least my friends and I clawed our way out of the hell we created for ourselves.&lt;/p&gt;

&lt;h1&gt;
  
  
  Technically
&lt;/h1&gt;

&lt;p&gt;AutoClass is also a reasonably efficient program in terms of the technologies used. The program's backbone is written in Python, with a library called &lt;code&gt;pyautogui&lt;/code&gt; for automation. The classes are picked using a spreadsheet, so it's easy for anyone to start with their classes and timings. The codebase is easy to work on, with a clear separation of concerns. &lt;/p&gt;

&lt;p&gt;After months of putting it off, I also implemented a functional UI to represent the program's state and classes, e.g., a color-coded list of all online classes. This allowed you to view your chosen settings, such as how long you wanted to attempt to join the class or your display colors.&lt;/p&gt;

&lt;p&gt;The program's entire history and the various updates it went through are preserved in the git history of the main AutoClass Git Repo.&lt;/p&gt;

&lt;h1&gt;
  
  
  I've graduated
&lt;/h1&gt;

&lt;p&gt;I'm happy to report, I've now graduated from Benchmark School System. With this comes the end of development of AutoClass since I'm no longer taking online classes.&lt;/p&gt;

&lt;p&gt;Throughout, AutoClass has been a very substantial project, and it will always have a place in my heart. Not because of the technical aspect of it, but because of the emotional factor of flying under the radar without flying too close to the sun.&lt;/p&gt;

&lt;h1&gt;
  
  
  Get In Touch
&lt;/h1&gt;

&lt;p&gt;👋 Hi, I’m &lt;a href="https://portfolio-dakheera47.vercel.app/"&gt;@DaKheera47&lt;/a&gt;, you may know me as Shaheer Sarfaraz&lt;/p&gt;

&lt;p&gt;👀 I’m interested in making web apps in React and Node, and you can view more of my projects &lt;a href="https://portfolio-dakheera47.vercel.app/"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;💻 I'm also passionate about automating everything to improve my day-to-day life&lt;/p&gt;

&lt;p&gt;🌱 Currently, I’m working as a Full Stack Web Developer at &lt;a href="https://www.pro-mirage.com"&gt;Project Mirage&lt;/a&gt;, a Design And Development Consultancy&lt;/p&gt;

&lt;p&gt;📫 I'm free to talk any time on my email address, &lt;a href="mailto:shaheer30sarfaraz@gmail.com"&gt;shaheer30sarfaraz@gmail.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>automation</category>
      <category>zoom</category>
      <category>python</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Why I Created Thousands Google Meet Links and Rate Limited My Account</title>
      <dc:creator>Shaheer Sarfaraz</dc:creator>
      <pubDate>Sat, 03 Sep 2022 08:04:41 +0000</pubDate>
      <link>https://forem.com/dakheera47/why-i-created-thousands-google-meet-links-and-rate-limited-my-account-4556</link>
      <guid>https://forem.com/dakheera47/why-i-created-thousands-google-meet-links-and-rate-limited-my-account-4556</guid>
      <description>&lt;h2&gt;
  
  
  The Idea
&lt;/h2&gt;

&lt;p&gt;It's simple really. What if you could have a Google Meeting with a code of your choosing.&lt;/p&gt;

&lt;p&gt;As you might already know, creating a new meeting with Google Meet creates a new link with a pattern of random unique letters at the end. The pattern looks like this &lt;code&gt;xxx-xxxx-xxx&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;My idea is to create thousands of these URLs in the hope that maybe one pops up with a phrase in it that I liked, maybe my name, maybe my initials, it could be anything.&lt;/p&gt;

&lt;p&gt;All in all, It's a project purely for fun. It's fun to just mess around every once in a while!&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Already Knew
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A new link can be generated by visiting a specific &lt;a href="https://meet.google.com/new"&gt;url&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Links are always unique and random&lt;/li&gt;
&lt;li&gt;A Google Account which creates a link is always its host&lt;/li&gt;
&lt;li&gt;A meeting link is re-usable after leaving&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How To Approach This Problem
&lt;/h2&gt;

&lt;p&gt;There were a few ideas on how to generate these meetings and get their links.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python + Selenium&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Selenium is a web browser automation tool, and there's bindings for the Selenium API in Python&lt;/p&gt;

&lt;p&gt;The Good&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;An advantage of using Selenium would be the ability to hide a browser window completely whilst it generated links using &lt;a href="https://stackoverflow.com/questions/46920243/how-to-configure-chromedriver-to-initiate-chrome-browser-in-headless-mode-throug"&gt;Headless Mode&lt;/a&gt;. This would allow the program to run in the background even when you were using your device&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The Bad&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Accessing a Google account in a Selenium driven window requires you to jump through quite a few hoops because of the possible breach in security this could lead to. This project needed to be built quickly, the quality of the code didn't matter too much because at the end of the day, this project won't ever serve a real purpose&lt;/li&gt;
&lt;li&gt;Before this, I'd only ever heard of Selenium and had a glance at the documentation, and never actually used it in a project, so there'd be a learning curve to overcome during this project too&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Python + &lt;code&gt;pyautogui&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The second idea, and the one I ended up going with was using Python and &lt;code&gt;pyautogui&lt;/code&gt; (a package to use a Python script to control the mouse and keyboard).&lt;/p&gt;

&lt;p&gt;The Good&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;There would be no browser compatibility issue, since I would be using my normal browser with its default Google Account.&lt;/li&gt;
&lt;li&gt;And, there'd be a easy and quick way to click on elements on screen. Simply take a screenshot of the element you want to click and reference it in your code. This completely avoids going through the pain of finding out which selector is precise enough in Selenium. &lt;/li&gt;
&lt;li&gt;Another positive for me was the fact that I had been using &lt;code&gt;pyautogui&lt;/code&gt; for a while before this for &lt;a href="https://github.com/DaKheera47/autoclass"&gt;AutoClass&lt;/a&gt;, so using it was almost second nature to me&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The Bad&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It's slower than Selenium for sure, but absolute speed just wasn't the main goal here.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  A Laundry List of Problems
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;How To Find Out When The URL Has Changed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The way I first imagined the program working was by looking at the URL bar of the browser. With Edge, whenever I joined a meeting, it would show a camera icon, indicating that the camera was being used. This of course would only happen after the page loaded up completely (and hence the link in the URL bar had changed from &lt;code&gt;https://meet.google.com/new&lt;/code&gt; to a new URL with the pattern), and since I could easily take a screenshot of anything on the screen and detect its presence and location, I felt this was a good place to start.&lt;/p&gt;

&lt;p&gt;Coding this up wasn't an issue, especially with the helper functions like &lt;a href="https://github.com/DaKheera47/autoclass/blob/43b13c9a090a34a332265e94a7df091eb76d1de4/helpers.py#L197"&gt;&lt;code&gt;findImageTimeout&lt;/code&gt;&lt;/a&gt; I had made previously which add some functionality which is actually on the roadmap of the &lt;code&gt;pyautogui&lt;/code&gt; package. As the name suggests &lt;code&gt;findImageTimeout&lt;/code&gt; attempts to find an image on screen using &lt;code&gt;pyautogui&lt;/code&gt;, and keeps attempting to find it until the specified timeout is up.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How To Get The URL From The URL Bar&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now I knew when the URL had updated to the new one, however I still hadn't gotten around to actually getting the URL into a variable. Checking to see if the camera was visible did help me in this case because the new URL is just slightly left of the where the camera icon appears. Now we know how to tell the program where to find the URL, but how to get it into a variable?&lt;/p&gt;

&lt;p&gt;Purely by chance, I had stumbled across this exact problem in an earlier project (more on that in another post), and I knew how to solve it now. Using &lt;code&gt;pyautogui&lt;/code&gt;, you can send hotkeys like &lt;code&gt;ctrl + c&lt;/code&gt; to copy and in Python, you can access the contents of the clipboard in a few different ways.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The one I used was &lt;code&gt;pyperclip&lt;/code&gt; because of its simplicity, and reliability.&lt;/li&gt;
&lt;li&gt;The second option was using &lt;code&gt;win32&lt;/code&gt;, which had extremely verbose syntax, and had to be executed with quite a few pauses with &lt;code&gt;time.sleep()&lt;/code&gt; to get it to work reliably, so it far slower, and more clunky to work with.&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;The Complete Roadmap&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So to get the URL from the browser, I can have the program click the URL bar slightly left of the coordinates of the camera icon, which automatically selects all the text in the field, then I can send a &lt;code&gt;ctrl + c&lt;/code&gt; using &lt;code&gt;pyautogui&lt;/code&gt; to copy the created URL into the clipboard. I can then read the clipboard using &lt;code&gt;pyperclip&lt;/code&gt;, and store it in a file.&lt;/p&gt;

&lt;h2&gt;
  
  
  v1.0
&lt;/h2&gt;

&lt;p&gt;After implementing the very initial concept of the project laid out above, here's some gripes I still had with the program.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clunky Codebase&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The code base at this time was very bodged together, almost feeling like it was different pieces of code just duct taped together without thought. The program wasn't too reliable either, eg if a link failed to load, then the program would be unable to handle it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Speed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I measured the performance of the script in terms of seconds per link. In its current state, the script was taking around 13-15 seconds per link. This was directly and severely impacted by my (at the time) subpar internet performance, and other factors like when Edge decided to show the camera icon.&lt;/p&gt;

&lt;h2&gt;
  
  
  v2.0
&lt;/h2&gt;

&lt;p&gt;Here comes the single biggest improvement to the speed of the program. &lt;/p&gt;

&lt;p&gt;The &lt;a href="https://meet.google.com/"&gt;Google Meet Homepage&lt;/a&gt; has an option to create the link for a later time. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ym988tD6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wyjccan756oofgr92tdz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ym988tD6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wyjccan756oofgr92tdz.png" alt="Create a link later" width="477" height="273"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Crucially for us, to create a new link, this option doesn't refresh the whole page. It loads a modal on the page, with just the link and a copy button.&lt;/p&gt;

&lt;p&gt;Conveniently, it also has a close button on the modal, which resets the state of the webpage. This means this loop can be repeated extremely quickly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--i6XdDjwq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0fvp5dks6ysc2le6r7q9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i6XdDjwq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0fvp5dks6ysc2le6r7q9.png" alt="Create a link later modal" width="880" height="485"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With this method, I brought the program down to about 2 seconds per link. We're looking at roughly a 750% improvement from our initial starting point of 15 seconds per link.&lt;/p&gt;

&lt;h2&gt;
  
  
  v2.1
&lt;/h2&gt;

&lt;p&gt;Previously, processes taking up fractions of a second wouldn't have made a significant performance improvement, since one link was taking 15 seconds. However now, with our time down to 2 seconds per link, I had to optimize these processes to improve speed further.&lt;/p&gt;

&lt;h3&gt;
  
  
  Find Images In Screenshots More Effectively
&lt;/h3&gt;

&lt;p&gt;One of the main areas where I could still improve was finding elements on the screen. Now seems like a good time to mention that just taking a screenshot of a 1080p display takes ~100ms, according to the &lt;code&gt;pyautogui&lt;/code&gt; &lt;a href="https://pyautogui.readthedocs.io/en/latest/screenshot.html#the-locate-functions:~:text=On%20a%201920%20x%201080%20screen%2C%20the%20screenshot()%20function%20takes%20roughly%20100%20milliseconds%20%2D%20it%E2%80%99s%20not%20fast%20but%20it%E2%80%99s%20not%20slow."&gt;docs&lt;/a&gt;. Finding an image within this screenshot would take far more time, and so this was a main point of concern for performance. This can be improved significantly and we'll see how later.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fractional Improvement
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;To prevent &lt;code&gt;pyautogui&lt;/code&gt; from attempting to find static objects (eg the "close" button and other similar non moving objects) on the entire screen, I had to hard code the exact pixel coordinates of these locations, and clicking on these pre-defined points as opposed to taking time to find them on screen.&lt;/li&gt;
&lt;li&gt;There was at least one element I couldn't hard code however, and that was the copy button in the modal. This is because there's no set time for it to appear. It could appear in 300ms, or it could take up to 1000ms, all subject to my internet connection.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I could optimize this further however. Considering we already know that the copy button will appear only in a specific area, we can search for the copy button in that (far smaller) area instead of the entire screen. This makes the search process as efficient as it can be.  &lt;/p&gt;

&lt;p&gt;All of this improvement resulted in sub-second time for each link generally around 0.75 seconds for every link. The largest performance bottleneck now was my internet connection, and I considered this a good enough place to stop working on it, and also because I got the link I wanted to find, a link with &lt;code&gt;dak&lt;/code&gt; in its pattern.&lt;/p&gt;

&lt;h2&gt;
  
  
  Being Rate Limited by Google
&lt;/h2&gt;

&lt;p&gt;Since this program was creating links automatically (and in sub-second time), of course I left it running overnight. After a few nights of creating links, I ran into a limitation set in place by Google. If I generated more than 5000 links in a span of one hour, I got rate limited. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5uUFizKN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dt8qgnay8u63z9dpiik6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5uUFizKN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dt8qgnay8u63z9dpiik6.png" alt="Image description" width="535" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This was evident because the modal, instead of showing the copy button with a new link, showed an error message. I found out this limitation was account-specific, and switching to another account meant you could go all the way again. I felt quite good about myself since this was one of my first web scraping / web automation projects, and getting rate limited by Google seemed like quite an achievement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some Interesting Observations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Google doesn't use the letter &lt;code&gt;L&lt;/code&gt; in any of its link patterns&lt;/li&gt;
&lt;li&gt;Google avoids common words in its links&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Github
&lt;/h2&gt;

&lt;p&gt;The Github Repo for the completed project is available &lt;a href="https://github.com/DaKheera47/meet-link-generator"&gt;here&lt;/a&gt;. Run &lt;code&gt;laterMethod.py&lt;/code&gt; to use the Homepage method.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get In Touch
&lt;/h2&gt;

&lt;p&gt;👋 Hi, I’m &lt;a href="https://portfolio-dakheera47.vercel.app/"&gt;@DaKheera47&lt;/a&gt;, you may know me as Shaheer Sarfaraz&lt;/p&gt;

&lt;p&gt;👀 I’m interested in making web apps in React and Node, and you can view more of my projects &lt;a href="https://portfolio-dakheera47.vercel.app/"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;💻 I'm also passionate about automating everything to improve my day-to-day life&lt;/p&gt;

&lt;p&gt;🌱 Currently, I’m working as a Full Stack Web Developer at &lt;a href="https://www.pro-mirage.com"&gt;Project Mirage&lt;/a&gt;, a Design And Development Consultancy&lt;/p&gt;

&lt;p&gt;📫 I'm free to talk any time on my email address, &lt;a href="mailto:shaheer30sarfaraz@gmail.com"&gt;shaheer30sarfaraz@gmail.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>automation</category>
      <category>showdev</category>
      <category>devjournal</category>
    </item>
  </channel>
</rss>
